为什么更新实体会将其子项的字段更改为null?

时间:2014-03-04 03:58:10

标签: java hibernate struts2 hibernate-mapping

我有两个ManyToOne关系的实体(产品和所有者)。问题在于,当我尝试更新Product实体时,表单中未包含的那些字段及其所有者实体的字段将更改为null。

实体

@Entity
@Table(name = "product")
@DynamicUpdate
public class Prodcut implements Serializable {
    private long id;
    private Owner owner;
    private String code;
    private String name;
    ....

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "owner")
    public Owner getOwner() {
        return owner;
    }

    public void setOwner(Owner owner) {
        this.owner = owner;
    }
}

@Entity
@Table(name = "owner")
@DynamicUpdate
public class Owner implements Serializable {
    private long id;
    ....
}

在这种情况下更新后,由于代码未包含在表单中,将更改为null,并且所有者的所有字段也将更改为null。

更新表单

<s:form method="POST" autocomplete="on" action="update">
                <input type="hidden" name="product.id" value="${product.id}"/>
                <s:select name="product.owner.id"
                          id="product.owner.id"
                          label="Owner"
                          list="listOfOwners"
                          headerKey=""
                          headerValue="Owner"
                          value="%{product.owner.id}"
                          />
               <input type="text" name="product.name" value="${product.name}"/>
               ....

Hibernate代码

 final Transaction tx = session.beginTransaction();
            try {

                Product product1 = (Product) session.get(Product.class,product.getId());
                Owner owner1 = (Owner) session.get(Owner.class, product.getOwner().getId());
                product.setOwner(owner1);
                product.setCode(product1.getCode);

                if (!tx.wasCommitted()) {    
                      tx.commit();
                }

                return pro;
            } catch (Exception e) {
                tx.rollback();
                e.printStackTrace();
            }

我尝试从数据库中检索产品对象并替换表单中未提供的那些字段的值,但它会遇到错误“具有相同标识符值的其他对象已与会话关联”。< / p>

1 个答案:

答案 0 :(得分:2)

最后一个策略是好的策略。您不能只是调用update()或任何其他方法:

Product persistentProduct = (Product) session.get(Product.class, product.getId());
persistentProduct.setName(product.getName());
// copy other fields
// nothing more