java JPA:关于在删除实体之前合并实体的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3876924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:48:16  来源:igfitidea点击:

JPA: question about merging an entity before removing it

javaormjpajakarta-eeejb

提问by Thang Pham

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:

我知道我必须在删除实体之前合并它,但我从没想过我必须在 EJB 中这样做。首先我有这些:

e = (Event) scholarBean.merge(e);
scholarBean.remove(e);

in my managed bean. It give me this error

在我的托管 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.

So then I bring those two lines inside my session bean, and it works. Any idea why?

然后我将这两行放在我的会话 bean 中,它可以工作。知道为什么吗?

Managed Bean

Managed Bean

myEJB.deleteEvent(e);

and

myEJB.java

myEJB.java

public void deleteEvent(Event e){
    e = (Event) merge(e);
    em.remove(e);
}

回答by Pascal Thivent

I know I have to merge the entity before removing it

我知道我必须在删除它之前合并实体

Not exactly. The object passed to remove has to be an entity and must not be detached. That's different.

不完全是。传递给 remove 的对象必须是一个实体并且不能被分离。那不一样。

but I never thought I have to do it inside EJB. First I have these (...)

但我从没想过我必须在 EJB 中这样做。首先我有这些(...)

Let's see what you're doing:

让我们看看你在做什么:

1: e = (Event) scholarBean.merge(e); 
2: scholarBean.remove(e);

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 detachedagain.

因此,在 中1:,您调用合并实体的 EJB(很可能具有事务范围的持久性上下文)。但是随后方法结束,事务提交,持久性上下文关闭,使返回的实体再次分离

And in 2:, you pass the (still) detached entity to an EJB and tries to removeit, which is not allowed. And KaBOOM!

在 中2:,您将(仍然)分离的实体传递给 EJB 并尝试使用remove它,这是不允许的。还有卡布姆!

So then I bring those two lines inside my session bean, and it works. Any idea why?

然后我将这两行放在我的会话 bean 中,它可以工作。知道为什么吗?

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 managedentity to remove.

它起作用是因为您现在正在与 JTA 事务关联的持久性上下文的范围内工作,因此您实际上将托管实体传递给remove.

回答by jos de jong

...and you can even combine those:

...你甚至可以结合这些:

Like so:

像这样:

    public void deleteManCheck(ManCheck manCheck) {
    em.remove(em.merge(manCheck));
}

回答by Frode Halvorsen

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.

当在 servlet 中使用它时,我遇到了相同的事务问题。当使用来自 MDB 的 EJB-service-bean 时,它工作正常,因为事务在 EJB 被调用之前启动,但是当 EJB 调用来自 servlet 时,没有正在运行的事务。我通过创建一个启动和提交 UserTransaction 的过滤器在我的 web 应用程序中解决了这个问题。然后每次调用 EJB 方法都会加入我的 UserTransaction 而不是启动它自己的事务。