1

Maybe this question has been anwsered, maybe not.

I want to update an object with optimistic lock, using

... EntityManager.merge(...); EntityManager.flush(...); ... 

My code works fine. What I want is update the version number in object and keep object reference.

I googling a long time, but I did not found the answer.

My last resort is make a nativeQuery and get the version number.

Here is the a test code:

 EntityManagerFactory factory = Persistence.createEntityManagerFactory(DBManager.getUnidadPersistencia()); EntityManager emA = factory.createEntityManager(); Grupo g = emA.find(Grupo.class, 1L); emA.close(); //In some place g.getSolicitanteList().get(0).setObservaciones("ZZZZ"); //Originally XXXX //... //Then I have to save the changes EntityManager emB = factory.createEntityManager(); EntityTransaction tx = emB.getTransaction(); try { tx.begin(); emB.merge(g); emB.flush(); tx.commit(); //Here comes exception emB.refresh(g); } catch (Exception e) { if (tx.isActive()) { tx.rollback(); } logger.log(Level.SEVERE, null, e); } emB.close(); 

And the stack trace:

30/07/2012 05:15:31 PM org.rp.co5parser.TestGrupo refreshTest GRAVE: null java.lang.IllegalArgumentException: Can not refresh not managed object: org.rp.co5parser.alojamiento.Grupo[ idGrupo=1 ]. at org.eclipse.persistence.internal.jpa.EntityManagerImpl.refresh(EntityManagerImpl.java:943) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.refresh(EntityManagerImpl.java:849) at org.rp.co5parser.TestGrupo.refreshTest(TestGrupo.java:89) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter.run(JUnit4TestMethodAdapter.java:109) at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:520) at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1060) at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:911) 

Is that ok?

Thanks in advance....

1 Answer 1

3

Before googling, read the documentation:

void refresh(java.lang.Object entity)

Refresh the state of the instance from the database, overwriting changes made to the entity, if any.

EDIT:

The error you get is not an OptimisticLockException. It's an IllegalArgumentException with a pretty clear error message: Can not refresh not managed object. You may only refresh an entity which is managed. And the object you pass is a detached object.

You wouldn't need to refresh the entity at all if you didn't ignore the result of merge(). merge() takes a detached object, copies its state to the managed (attached) object with the same ID, and returns the managed object. So you should just need to do:

try { tx.begin(); g = emB.merge(g); // assign the merged, attached object, having the new version to g tx.commit(); // no need to flush. commit flushes automatically } catch (Exception e) { if (tx.isActive()) { tx.rollback(); } logger.log(Level.SEVERE, null, e); } emB.close(); 
Sign up to request clarification or add additional context in comments.

3 Comments

I know that. But, when I use that method it throws OptimisticLockException.
Show us your code, the complete stack trace, ans tell us the line in the code which throws this exception.
Thanks! I am very new using JPA.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.