为什么我的update()方法创建一个新实例?

时间:2016-08-18 02:41:03

标签: java-ee ejb crud enterprise facade

我的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" />

知道发生了什么事吗?

感谢。

1 个答案:

答案 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对象,因为您没有提供现有的对象,那么您将获得您所看到的重复效果。