我的J2EE应用程序中的数据库的基本CRUD操作存在问题。
实体:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "shop_id")
门面:
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public void edit(T entity) {
getEntityManager().merge(entity);
}
}
控制器(我添加了S.out以查看会发生什么):
public String updateShop(Shop shop){
System.out.println("Update ");
System.out.println(this.shop.getName()+" - ID: "+ this.shop.getShopId());
this.shop = shop;
return "updateShop";
}
public String updateShop(){
System.out.println("UpdateClick ");
System.out.println(this.shop.getName()+" - ID: "+ this.shop.getShopId());
this.shopfacade.edit(this.shop);
return "shops";
}
当我点击更新时,会创建一个新实例,而不是修改现有实例。这是服务器的日志输出:
Info: Update
Info: Name - 41
Info: UpdateClick
Info: ChangedName - null
所以Id不知何故消失了。这发生在我调用updateShop()的那一刻,因为我在我的JSF页面上显示了ID并且它工作正常。
<h:outputText value="#{shopController.shop.shopId}" title="shopId" />
知道发生了什么事吗?
感谢。
答案 0 :(得分:0)
你的一个问题是javax.persistence.EntityManager.merge返回一个实体对象 - 你的代码忽略了它。
此返回的实体可能与您传入的实体相同或不同。通常,如果当前的持久性上下文已经引用了您传入的实体,则该实体将是返回的实体。
因此,updateShop()
可能应该是这样的:
public String updateShop(){
System.out.println("UpdateClick ");
System.out.println(this.shop.getName()+" - ID: "+ this.shop.getShopId());
this.shop = this.shopfacade.edit(this.shop);
return "shops";
}
其次,将没有主键的实体bean传递给merge
实际上与将其传递给persist
相同。因此,如果JSF必须new
它自己的Shop
对象,因为您没有提供现有的对象,那么您将获得您所看到的重复效果。