在hibernate中更新对象的字段

aks*_*hay 8 java merge hibernate save

我有一个object A映射到table ADB的

class A {
     Integer id;
     String field2,field2;field3 ,... fieldN;
     //lots of other attribute
}
Run Code Online (Sandbox Code Playgroud)

现在我想编写一个只更新单个字段的DAO api.一种方法是我可以先加载对象然后更改我需要的属性然后使用merge api

//start transcation
A a = session.load(A.class, id);
A.setfieldP(newValue)
session.merge(A)
//commit transcation
Run Code Online (Sandbox Code Playgroud)

现在,如果我使用以下代码

 //start transcation
 A a = new A();
 a.setId(id); //set a id by which object A exists in DB
 A.setfieldP(newValue)
 session.merge(A)
 //commit transaction
Run Code Online (Sandbox Code Playgroud)

现在第二种方法除了id和fieldP之外的所有字段都设置为null

1)现在还有其他方法吗?
2)我可以使用更新而不是合并吗?

Rus*_*ard 13

如果您需要一次更新大量实体,最有效的方法是使用查询:

Query query = session.createQuery("update EntityName set fieldP = 'newValue' "
        + "where id IN (75, 76)");
query.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

这允许您在不将实体或实体加载到内存中的情况下更改字段值.

最好的做法是使用命名查询和命名参数 - 上面的实现只是一个例子.

  • 我不同意.首先,他要求采用不同的方法,如果有的话.其次,从他的第二个代码片段可以清楚地看出,他希望避免将实体加载到内存中. (6认同)

Pau*_*ald 2

我通常更喜欢 session.get 与 session.load,因为 session.get将返回 null而不是抛出异常,但这取决于您想要的行为。

加载对象,设置字段,然后调用

 session.merge(myObject)
Run Code Online (Sandbox Code Playgroud)

是标准方法,尽管您也可以使用

 session.saveOrUpdate(myObject)
Run Code Online (Sandbox Code Playgroud)

只要该对象尚未分离,在您的情况下,它就不会被分离。这是一篇很好的文章,解释了 merge 和 saveOrUpdate 的差异。

在第二个示例中,您正在编辑对象的主键?这通常是不好的形式,您应该删除并插入而不是更改主键。