Jsf 为什么JPA在我尝试删除实体时表现得像我的实体被分离一样,而在我编辑实体时却不是?
所以我有一个基本的JSF数据表,相关部分是:Jsf 为什么JPA在我尝试删除实体时表现得像我的实体被分离一样,而在我编辑实体时却不是?,jsf,jpa,Jsf,Jpa,所以我有一个基本的JSF数据表,相关部分是: <h:dataTable value="#{actorTableBackingBean.allActors}" var="actor"> <h:column headerText="Actor Name" sortBy="#{actor.firstName}"> <h:outputText value="#{actor.firstName}" /> </h:column>
<h:dataTable value="#{actorTableBackingBean.allActors}" var="actor">
<h:column headerText="Actor Name" sortBy="#{actor.firstName}">
<h:outputText value="#{actor.firstName}" />
</h:column>
<h:column>
<h:form>
<h:commandButton value="Delete Actor"
action="#{actorTableBackingBean.deleteActor(actor)}"/>
</h:form>
</h:column>
<h:column>
<h:form>
<h:commandButton value="Randomize Actor Name"
action="#{actorTableBackingBean.editActor(actor)}"/>
</h:form>
</h:column>
</h:dataTable>
即使我尝试:
public void deleteActor(Actor a){
em.merge(a);
em.remove(a);
}
我仍然得到同样的例外
那么它是如何编辑行的,而不是删除行的呢
我能让它工作的唯一方法是:
public void deleteActor(Actor a){
Actor actorToBeRemoved = getWithId(a.getActorId());
em.remove(actorToBeRemoved);
}
我做错了什么,或者我不能理解什么 merge()方法执行以下操作:它获取分离的实体,从数据库加载具有相同ID的附加实体,将分离实体的状态复制到附加实体,然后返回附加实体。正如您在本说明中所注意到的,分离的实体根本不会修改,也不会附着。这就是为什么会出现异常
如果你得到了,你就不会得到它
public void deleteActor(Actor a){
a = em.merge(a); // merge and assign a to the attached entity
em.remove(a); // remove the attached entity
}
也就是说,合并是完全不必要的,因为您只需要删除实体。最后一个解决方案很好,只是它确实从数据库加载了实体,这也是不必要的。你应该做的很简单
public void deleteActor(Actor a){
Actor actorToBeRemoved = em.getReference(Actor.class, a.getActorId());
em.remove(actorToBeRemoved);
}
请注意,您的getWithId()
方法效率低下,而且不必要地复杂。你应该把它换成
public Actor getWithId(int id){
return em.find(Actor.class, id);
}
这将使用第一级缓存(可能还有第二级缓存)来避免不必要的查询。对不起,您能解释一下em.remove(em.contains(entity)?entity:em.merge(entity))是如何实现的吗;工作在巴卢斯的回答中:这不是同样的情况吗?合并应该是不够的,对吗?如果
em
不包含实体,则此语句可归结为em.remove(em.merge(entity))
,这意味着:删除em.merge(entity)
返回的实体。因此,它确实删除了由em.merge()
返回的附加实体。方法em.get(Class entityClass,Object primaryKey)
不可用。它应该是方法em.find(类entityClass,对象primaryKey)
(在上一个代码片段中)?这是一个非常简单的解决方案,但我花了2个多小时寻找它。使用JPA管理DB内容是多么容易,这令人惊讶。@jbnitet将em.remove(em.getReference(…)
也能工作吗?
public void deleteActor(Actor a){
a = em.merge(a); // merge and assign a to the attached entity
em.remove(a); // remove the attached entity
}
public void deleteActor(Actor a){
Actor actorToBeRemoved = em.getReference(Actor.class, a.getActorId());
em.remove(actorToBeRemoved);
}
public Actor getWithId(int id){
return em.find(Actor.class, id);
}