问题描述
也许我只是给了您一小段代码而过分简化了(如果是这种情况,我会发布更多),但我认为起初,越少越好:
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:
我有一个Asset类型的实体,该实体具有一个Location类型的字段,它也是一个实体.设置资产的位置时,还必须设置其子级的位置.
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();
运行flush()时,出现以下异常:
When I run flush(), I get the following exception:
内部异常:java.sql.SQLIntegrityConstraintViolationException:ORA-00001:违反了唯一约束(SWRADMIN.LOCATION_PK)
我的问题是...为什么这个Location对象甚至试图被持久化?我要做的就是在实体中设置变量.
My question is...why is this Location object even trying to be persisted? All I'm doing is setting a variable in an entity.
以前运行良好,但是我们只是切换到使用Eclipselink和Java EE 6,然后弹出此问题.
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.
推荐答案
如果对象处于托管状态,则实体管理器将通过隐式持久存储对象(可能在事务结束时)将其与基础数据库同步.明确地在调用em.flush()
方法时.
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.
您可以使用em.detach(entity)
分离单个实体,或者使用em.clear()
分离所有实体.这样,对实体进行的更改将不会反映在数据库中.
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.
要更好地处理此问题,可以使用BMT(Bean管理的事务),在该操作中,您必须手动处理实体持久性事务.
To better handle this, you can use BMT (Bean Managed Transaction), where you have to handle the entity persistence, transaction manually.
Location location = asset.getLocation();
childAsset.setLocation(location);
em.merge(childAsset);
em.flush();
这篇关于EntityManager尝试在没有提示的情况下插入实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!