Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
650 views
in Technique[技术] by (71.8m points)

jpa - EntityManager trying to insert entities without being prompted

Perhaps I'm over-simplifying this by only giving you a small snippet of code (and I'll post more if that is the case) but I figure, initially, less is better:

I have an entity of type Asset which has a field of type Location, which is also an entity. When I set the Location of an Asset I must also set the Location of its children.

Location location = asset.getLocation();
em.merge(location);
em.flush();

childAsset.setLocation(asset.getLocation());
em.flush();

When I run flush(), I get the following exception:

Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (SWRADMIN.LOCATION_PK) violated

My question is...why is this Location object even trying to be persisted? All I'm doing is setting a variable in an entity.

This was working fine before, but we just switched to using Eclipselink and Java EE 6 and this problem popped up.

Solution?: I used the idea of "detaching" from below and made the following change:

Location location = asset.getLocation();

em.detach(childAsset);
childAsset.setLocation(asset.getLocation());
em.merge();
em.flush();

and it worked! I'm confused as to why, though...you would think the auto-syncing would do the same thing.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If the object is in managed state, then entity manager will synchronize it with the underlying database by persisting the object implicitly (probably at the end of the transaction) or explicitly when you call em.flush() method.

You can use em.detach(entity) to detach a single entity or em.clear() to detach all the entities. Then the changes being made on an entity/entities will not get reflected in the database.

To better handle this, you can use BMT (Bean Managed Transaction), where you have to handle the entity persistence, transaction manually.

Edit :

Location location = asset.getLocation();
childAsset.setLocation(location);
em.merge(childAsset);
em.flush();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...