所以我有一个基本的JSF Datatable,相关部分是:
<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>
Run Code Online (Sandbox Code Playgroud)
这就是ActorTableBackingBean的样子:
@Named
@RequestScoped
public class ActorTableBackingBean implements Serializable {
@Inject
ActorDao actorDao;
private List<Actor> allActors;
public List<Actor> getAllActors() {
return allActors;
}
@PostConstruct
public void fillUp(){
allActors = actorDao.getAllT();
}
public String deleteActor(Actor a){
removeActor(a);
return "/allActors.xhtml";
}
private String removeActor(Actor a){
try{
actorDao.deleteActor(a);
return null;
}catch (Exception e){
return null;
}
}
public String editActor(Actor actor){
actor.setFirstName("SomeRandonName");
actorDao.editActor(actor);
return "/allActors.xhtml";
}
}
Run Code Online (Sandbox Code Playgroud)
最后是演员道:
@Stateless
public class ActorDao extends GeneralDao<Actor> implements Serializable {
@Override
protected Class<Actor> getClassType() {
return Actor.class;
}
@Override
public Actor getWithId(int id){
TypedQuery<Actor> typedQuery =
em.createQuery("Select a From Actor a WHERE a.actorId =" + id,Actor.class);
return typedQuery.getSingleResult();
}
public void editActor(Actor a){
em.merge(a);
}
public void deleteActor(Actor a){
em.remove(a);
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可以看到编辑Actor调用em.merge(a),这很好用.但是,em.remove(a)将返回:
Caused by: java.lang.IllegalArgumentException: Entity must be managed to call remove: com.tugay.sakkillaa.model.Actor@6ae667f, try merging the detached and try the remove again.
Run Code Online (Sandbox Code Playgroud)
即使我尝试:
public void deleteActor(Actor a){
em.merge(a);
em.remove(a);
}
Run Code Online (Sandbox Code Playgroud)
我仍然得到同样的例外.
那么它如何用于编辑行,而不是用于删除它?
我唯一能让它发挥作用的方式是:
public void deleteActor(Actor a){
Actor actorToBeRemoved = getWithId(a.getActorId());
em.remove(actorToBeRemoved);
}
Run Code Online (Sandbox Code Playgroud)
我做错了什么或者无法理解的是什么?
JB *_*zet 41
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
}
Run Code Online (Sandbox Code Playgroud)
也就是说,合并是完全没必要的,因为您要做的就是删除实体.最后一个解决方案很好,除了它真正从数据库加载实体,这也是不必要的.你应该这样做
public void deleteActor(Actor a){
Actor actorToBeRemoved = em.getReference(Actor.class, a.getActorId());
em.remove(actorToBeRemoved);
}
Run Code Online (Sandbox Code Playgroud)
请注意你的 getWithId()方法效率不高,而且不必要地复杂.你应该用它替换它
public Actor getWithId(int id){
return em.find(Actor.class, id);
}
Run Code Online (Sandbox Code Playgroud)
它将使用第一级缓存(也可能是第二级缓存)以避免不必要的查询.
| 归档时间: |
|
| 查看次数: |
18009 次 |
| 最近记录: |