Hibernate使用新对象更新现有实体

时间:2010-03-26 09:13:16

标签: hibernate

假设我在DB中有一个实体Foo。

我正在解析一些文件并创建新的Foo对象,并希望检查DB中是否存在已解析的Foo对象(使用唯一属性)。如果它已存在已更新,否则另存为新对象。

最好的方法是什么?

我可以简单地在新的Foo对象中设置id和版本吗?

或者我最好从数据库加载Foo对象并从解析文件中复制属性?

感谢。

3 个答案:

答案 0 :(得分:2)

让我们说Foo有一些大小,颜色和对齐的属性。

所以数据库中的Foo具有这些属性(并且您已经使用uniqueness属性确定这是正确的)

id=1, size=12, color=null, alignment="c"

然后让我们说新的Foo(newFoo)对象具有以下属性

id=(none yet), size=14, color="red", alignment=null

您拥有的选项是使用saveOrUpdate()方法或merge()方法。两者都将导致新对象保存在旧对象上,但保留旧对象的id。 存储的新对象将具有上面的newFoo属性,但id设置为1。

但是,如果您只想覆盖Foo的某些属性,则可能必须从数据库加载对象并手动复制它们。例如,在这种情况下,对齐将被null覆盖。如果您希望仅在新值不为空的情况下覆盖对齐,那么我认为您需要手动复制值。

答案 1 :(得分:0)

如果您不确定该实体是否在数据库中,那么它可能是分离的实体。您可以通过设置id和所有其他字段并调用“saveOrUpdate”来让hibernate选择是保存还是更新实体。这就是文档中的所有内容 - section 10.7

答案 2 :(得分:-1)

如果您正在解析的文件中没有id,那么您的对象是如此复杂以至于使用hql来更新它不是一个选项吗?

喜欢:

getHibernateTemplate().bulkUpdate("Update Foo set p1 = ?, ... where uniq_prop = ?", new Object[] {..., key});

如果您首先加载实体,您将发出select by update,这将使您将发送到数据库的请求加倍。 hql update选项还有一个优点,就是不用许多对象加载你的hibernate会话(当解析一个大文件时,会话大小可能会成为要监视的东西)。