所以我正在开发一个 web 应用程序,并尝试使用 JPA 来访问我的数据库。我使用 EJB 从我的数据库中获取实体,但是,如果我从 EJB 获取另一个实例并对其进行更改,则这些更改不会反映在我的旧实体中。此外,当我尝试刷新旧实体时,我收到一条错误消息,指出该实体不受管理。我可以设计一个解决方法,我只是想知道我做错了什么?
1 回答
好的,看起来如下。
EJB + JPA 存在于 EJB 容器中。您的 Web 应用程序位于 Web 应用程序容器中。这两个容器都是应用服务器的一部分,但它们之间的通信就像 Web Container 只是一个 EJB 组件客户端一样。
因此,基本上,您有典型的客户端(Web 应用程序)-服务器(EJB + JPA)场景。
现在,如果您将实体从 EJB 带到客户端,它不知道在服务器上所做的更改 - 它只是您在客户端拥有的普通对象(它“忘记”了它的 EJB/JPA 来源)。这就是为什么您在 Web 应用程序中看不到任何更改的原因,即使您正在更改 EJB 容器中的类似实体。
您必须手动同步客户端对象和保存在 EJB 容器中的对象。
第二个问题 - 实体不受管理。当您将实体从客户端发送到 EJB 容器时,EJB 容器不会对该实体做出任何假设 - 它会将其视为普通对象。
为了告诉 EJB 容器“嘿,看,该实体不仅仅是一些随机对象,它是我希望您管理的实体”,您需要EntityManager.merge(entity)
在执行任何进一步操作之前调用该对象方法。
此方法将实体添加到持久上下文缓存并返回附加到实体管理器会话的对象。
这很重要!您需要修改正确的对象
Object addedToEM = EntityManager.merge(entity)
如果要在服务器端进行任何更新,则需要修改 addedToEM 实体(参见例如JPA EntityManager:Why use persist() over merge()?以获得很好的解释)。