JPA:有关在删除实体之前合并实体的问题
我知道在删除实体之前必须合并该实体,但我从未想过必须在 EJB 内部执行此操作。首先,我有这些:
e = (Event) scholarBean.merge(e);
scholarBean.remove(e);
在我的托管 bean 中。它给了我这个错误
java.lang.IllegalArgumentException: Entity must be managed to call remove: com.scholar.entity.Event@998, try merging the detached and try the remove again.
,然后我将这两行放入我的会话 bean 中,它就可以工作了。知道为什么吗?
托管 Bean
myEJB.deleteEvent(e);
和
myEJB.java
public void deleteEvent(Event e){
e = (Event) merge(e);
em.remove(e);
}
I know I have to merge the entity before removing it, but I never thought I have to do it inside EJB. First I have these:
e = (Event) scholarBean.merge(e);
scholarBean.remove(e);
in my managed bean. It give me this error
java.lang.IllegalArgumentException: Entity must be managed to call remove: com.scholar.entity.Event@998, try merging the detached and try the remove again.
So then I bring those two lines inside my session bean, and it works. Any idea why?
Managed Bean
myEJB.deleteEvent(e);
and
myEJB.java
public void deleteEvent(Event e){
e = (Event) merge(e);
em.remove(e);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不完全是这样。传递给remove的对象必须是一个实体并且不能被分离。那是不同的。
让我们看看您在做什么:
因此,在
1:
中,您调用合并实体的 EJB(很可能具有事务范围的持久性上下文)。但随后该方法结束,事务提交,持久性上下文关闭,使返回的实体再次分离。在
2:
中,您将(仍然)分离的实体传递给 EJB 并尝试删除
它,这是不允许的。还有卡轰!它之所以有效,是因为您现在正在与 JTA 事务关联的持久性上下文的范围内工作,因此您实际上是将一个托管实体传递给
remove
。Not exactly. The object passed to remove has to be an entity and must not be detached. That's different.
Let's see what you're doing:
So in
1:
, you call an EJB (very likely with a transaction-scoped Persistence Context) that merges the entity. But then the method ends, the transaction commits, the Persistence Context gets closed, making the returned entity detached again.And in
2:
, you pass the (still) detached entity to an EJB and tries toremove
it, which is not allowed. And KaBOOM!It works because you're now working within the scope of the persistence context associated to the JTA transaction and you're thus really passing a managed entity to
remove
....你甚至可以将它们结合起来:
像这样:
...and you can even combine those:
Like so:
当在 servlet 中使用它时,我遇到了相同的事务问题。当从 MDB 使用 EJB-service-bean 时,它工作得很好,因为事务是在调用 EJB 之前启动的,但是当 EJB 调用来自 servlet 时,没有正在运行的事务。
我通过创建一个启动并提交 UserTransaction 的过滤器在我的 web 应用程序中解决了这个问题。然后,对 EJB 方法的每次调用都会加入我的 UserTransaction,而不是启动它自己的事务。
I had the same transaction-issues when this was used in a servlet. When using the EJB-service-bean from a MDB it worked fine, since the transaction was started before the EJB was called, but when the EJB-call came from a servlet, there was no running transaction.
I solved this in my webapp by creating a filter that starts and commis a UserTransaction. Then every call to the EJB-methods joins my UserTransaction instead of starting it's own transaction.