I use this code to made a copy of entity:
EntityClass obj = em.find(...);
em.detach(obj);
obj.setId(null);
obj.setName("New");
em.persist(obj);
em.flush();
So the issue is - if i do a new copy from this created copy, they both points to the last created copy in entity manager cache!
// Call#1 copy method
Entity obj = em.find(Entity.class, 1); // old object, id = 1
em.detach(obj);
obj.setId(null);
em.persist(obj); // created new object with id = 2
em.flush();
// Call#2 copy method
Entity obj2 = em.find(Entity.class, 2); // our copy, id = 2
em.detach(obj2);
obj2.setId(null);
em.persist(obj2); // created new object with id = 3
em.flush();
// Call another method
Entity someObj = em.find(Entity.class, 2); // returns last copy with id=3!
// it's like after persist obj2 (id=2) points
// to the same memory address as the new copy with id = 3
evictAll() after copy method execution makes it upside down - now id=2 and id=3 both points to the original copy with id=2. I assume this somehow connected with fact that in Java we do not create new object with constructor, and variable stays the same while in database exists two entities.
The root of the problem is the major clash between you and JPA:
So instead of using JPA, you are fighting it.
If you try to follow the suit, you will end up with something brittle and ugly - and you will also a feeling that JPA is somehow failing you (same feeling you get when you try to hammer nails with a screwdriver).
What you need to do to get this to work nicely, is:
You might end up with elegant, testable code that has no explicit cache operations, no flushes, no "merge" and no "detach".
Sorry, I know this is not the type of advice you wanted to hear. if you want to get into the JPA mindset and see the rationale for JPA's behavior, check out classic Fowler's enterprise patterns, especially Unit of Work and Identity Map