Our java application is using Toplink JPA to connect the data access layer to our SQL Server 2008 database.
We can query the database and get our results without any issue. The problem is that if we try and change the returned entity, it persists to the database as soon as the setter is called.
Query rQuery = em.createNamedQuery("Region.findAll");
Region r= rQuery.getResultList();
r.setActive(active);
From what we've been reading on JPA, it seems like it shouldn't send the changes to the database until persist/merge/flush is called. This is the behavior we're looking to have. We want to be able to make all of our changes and then send them all at once. If we send them one at a time and we get an error, we could end up with partially updated records.
I've tried setting the entity manager flush mode to commit in order to force it to wait for a commit call before persisting and it didn't make any difference.
em.setFlushMode(FlushModeType.COMMIT);
I also tried detaching the returned entity before calling the setters, but it throws an exception.
java.lang.AbstractMethodError: oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.detach(Ljava/lang/Object;)
This is our first time using Toplink JPA and we don't know what else to try. If anyone has any other suggestions on how to fix this issue I'd really appreciate it.
If your updating code to the entity is done within a method marked with a transaction then by the end of that method changes will be committed since the transaction must commit any changes before it closes.
Merge is used if the entity is detached ,you made some changes to that entity and you need to re-attach it again and merge the update in the database.
The solution is to make the query for data in a different method with transaction attribute 'Require_new' and pass the result set to the method that do the update with transaction attribute 'required' or 'mandatory'.