Jsf 为什么JPA在我尝试删除实体时表现得像我的实体被分离一样,而在我编辑实体时却不是?

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>

所以我有一个基本的JSF数据表,相关部分是:

<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);
}