3

I am implementing a feature where if there is any exception while writing data into DB, we should retry it for 5 times before failing. I have implemented the feature but not able to test it using arquillian test.

We are using JPA and Versant as database. Till now, I am debbuging the the arquillian test and once my flow reaches DB handler code, I am stopping the database. But this is worst way of testing.

Do you have any suggestion how to achieve the same ?

sauumum
  • 1,638
  • 1
  • 19
  • 36

2 Answers2

0

Native solutions

There is the old trick by dividing by zero in the database. At the time of selection you could try:

select 1/0 from dual;

Insertion time (you need a table):

insert into test_table (test_number_field) values (1/0);

pure JPA solution

You can try to utilize the @Version annotation and decrement it to throw OptimisticLockException. This is not thrown in the database, but in the Java layer, but fullfills your need.

Those all will result in DB fail.

Hash
  • 4,647
  • 5
  • 21
  • 39
  • the guy is using JPA, you cannot run ad-hoc queries, you need to map queries to classes (entitities). – Mitja Gustin Aug 09 '16 at 10:41
  • You are able to do it, see **Utilizing Native SQL Queries**: http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html – Hash Aug 09 '16 at 10:42
  • Of course, I think he's asking how to get JPA code throw error's in runtime, and yes the way is native queries, as I suggested in my answer. – Mitja Gustin Aug 09 '16 at 10:56
  • Well I forgot to mention `OptimisticLockException` previously... that would be a nice solution to it. – Hash Jul 11 '17 at 17:53
0

With JPA in mind, the easiest way is to add method to your data access layer, with which you are able to run native queries. Then you run query against nonexisting table or something similar. So in my DAO utilities I found method like this:

public List findByNativeQuery(String nativeQuery, Map<String, Object> args) {

    try{

        final EntityManager em = getEntityManager();
        final Query query = em.createNativeQuery(nativeQuery);

        if (args!=null && args.entrySet().size()>0) {
            final Iterator it = args.entrySet().iterator();
            while (it.hasNext()) {
                final Map.Entry pairs = (Map.Entry)it.next();
                query.setParameter(pairs.getKey().toString(), pairs.getValue());
            }
        }

        return query.getResultList();

    }
    catch (RuntimeException e) {
        // throw some new Exception(e.getMessage()); // the best is to throw checked exception
    }

}
Mitja Gustin
  • 1,723
  • 13
  • 17
  • I need to test this in an integration test. I don't want to change my actual code (as this is what will shipped) but still I want to make DB unavailable for some period of time while my integration test is running . – sauumum Aug 09 '16 at 14:49
  • Then use inmemory database for this purpuse. Start it with java code snippet. Jboss has database just for this purpuse. You declare its redources in src/test/resources. HQSql. – Mitja Gustin Aug 14 '16 at 20:26