4 Replies Latest reply on May 16, 2014 10:52 AM by fantarama

    Java batch (JSR352), JPA and chunk transactions problem

    fantarama

      Hi,

      I've wrote a simple java batch job with a single chunk that read a csv file and for each row build and persist a simple JPA entity. I've configured the chunk with a commit interval of 7 items. As explained on JSR352 the transaction is bound to the entire chunk so I expected that if an exception occured during the chunk process (in my code on a failure item write) the transaction rollback all the entities persisted by the active chunk.

       

      The problem is that during ItemWriter processing, inside the loop, I do an EntityManager.persist(myitem) (the EntityManager is injected with @PersistenceContext) and synchronously hibernate send and commit the insert sql as there is no transaction active (or a kind of autocommit), before the method exit. If the loop throw and exception the only effect is the job end, but entities persisted in the chunk are still there on the database!

       

      Same code on Glassfish 4 work fine

       

      Using the same injected persistence unit outside the job context (like an ejb timer) transactions works, so i suppose that is not a datasource configuration issue.

       

      Any idea? Am I missing some extra configuration for java batch transactions?

        • 1. Re: Java batch (JSR352), JPA and chunk transactions problem
          jamezp

          In the batch spec each read, process and write is done in a separate transaction. If you use the same EntityManager in multiple chunks the connection persists across transaction boundaries. IMO for EE the batch spec is broken. If you're on WildFly 8.1.x however you can add a property jberet.local-tx with a value of true to your job properties, step configuration in the job.xml or the job configuration in the job.xml. This will use a local transaction instead of the enlisted transaction and hibernate should take care of the transaction boundaries.

           

          --

          James R. Perkins

          1 of 1 people found this helpful
          • 2. Re: Re: Java batch (JSR352), JPA and chunk transactions problem
            fantarama

            Thank you,

             

            the problem is that the transaction is not active even in the single write chunk, I'm not looking for a transaction across read and write; my code:

             

            @PersistenceContext

            EntityManager em;

             

            @Override

            public void writeItems(List<Object> items) throws Exception {

                for (Object i : items) {

                     MyEntity e = new MyEntity();

                     ... some code ...

                     em.persist(e);

                }

            }

             

            The above code insert and commit the entity on each loop iteration instead of the end of the method. If an exception occur iside the loop entities persisted in previous iteration didn't rollback.

             

            I don't need a custom transaction management, I need to understand why there is no transaction at all!

            • 3. Re: Java batch (JSR352), JPA and chunk transactions problem
              fantarama

              UPDATE

               

              With a new Wildfly installation and reconfiguring the datasource, the tranasctions work. May be an issue related to JTA datasource configuration with mysql?

              • 4. Re: Java batch (JSR352), JPA and chunk transactions problem
                fantarama

                ** SOLVED **

                 

                The problem source was the Entity id strategy: set to IDENTITY Hibernate with MySQL do the insert after the persist method, with AUTO or a manual set the inserts sql are flushed at the end of the transaction.

                 

                Now my question is: is this a know scenario or i've found some kind of bug?