当前位置:  开发笔记 > 编程语言 > 正文

Hibernate中不同的保存方法有什么区别?

如何解决《Hibernate中不同的保存方法有什么区别?》经验,为你挑选了6个好方法。

Hibernate有一些方法,以这种或那种方式,获取对象并将其放入数据库.它们之间有什么区别,什么时候使用哪个,为什么不存在一个知道何时使用什么的智能方法?

到目前为止我发现的方法是:

save()

update()

saveOrUpdate()

saveOrUpdateCopy()

merge()

persist()

Lee Theobald.. 117

这是我对这些方法的理解.主要是这些是基于API,但我没有在实践中使用所有这些.

saveOrUpdate 根据某些检查调用保存或更新.例如,如果不存在标识符,则调用save.否则调用更新.

保存 持有实体.如果不存在标识符,将分配标识符.如果有的话,它实质上是在进行更新.返回生成的实体ID.

update 尝试使用现有标识符持久保存实体.如果不存在标识符,我认为会抛出异常.

saveOrUpdateCopy 这是不推荐使用的,不应再使用.而是......

合并 现在这是我的知识开始蹒跚的地方.这里重要的是瞬态,分离和持久实体之间的区别.有关对象状态的更多信息,请查看此处.通过保存和更新,您将处理持久对象.它们链接到一个Session,因此Hibernate知道发生了什么变化.但是当你有一个瞬态对象时,就没有涉及会话.在这些情况下,您需要使用merge进行更新并保留以进行保存.

persist 如上所述,这用于瞬态对象.它不会返回生成的ID.



1> Lee Theobald..:

这是我对这些方法的理解.主要是这些是基于API,但我没有在实践中使用所有这些.

saveOrUpdate 根据某些检查调用保存或更新.例如,如果不存在标识符,则调用save.否则调用更新.

保存 持有实体.如果不存在标识符,将分配标识符.如果有的话,它实质上是在进行更新.返回生成的实体ID.

update 尝试使用现有标识符持久保存实体.如果不存在标识符,我认为会抛出异常.

saveOrUpdateCopy 这是不推荐使用的,不应再使用.而是......

合并 现在这是我的知识开始蹒跚的地方.这里重要的是瞬态,分离和持久实体之间的区别.有关对象状态的更多信息,请查看此处.通过保存和更新,您将处理持久对象.它们链接到一个Session,因此Hibernate知道发生了什么变化.但是当你有一个瞬态对象时,就没有涉及会话.在这些情况下,您需要使用merge进行更新并保留以进行保存.

persist 如上所述,这用于瞬态对象.它不会返回生成的ID.


我想接受这个作为答案,但有一点仍然不清楚:因为save()回退到update(),如果这样的项目存在,它在实践中与saveOrUpdate()有什么不同?
如果你对merge/persist的描述只对瞬态对象有重要意义,那么这很有意义并且适合我们如何使用hibernate.另请注意,与更新相比,合并通常具有性能限制,因为它似乎需要额外获取某种类型的完整性检查.
鉴于hibernate可能知道对象所处的状态,为什么我们必须在编写程序时手动执行此操作.应该只有一种保存方法.

2> Sergii Shevc..:
?????????????????????????????????????????????????????????????????????????????????
?    METHOD    ?            TRANSIENT          ?            DETACHED            ?
?????????????????????????????????????????????????????????????????????????????????
?              ?       sets id if doesn't      ?   sets new id even if object   ?
?    save()    ?     exist, persists to db,    ?    already has it, persists    ?
?              ?    returns attached object    ? to DB, returns attached object ?
?????????????????????????????????????????????????????????????????????????????????
?              ?       sets id on object       ?             throws             ?
?   persist()  ?     persists object to DB     ?       PersistenceException     ?
?              ?                               ?                                ?
?????????????????????????????????????????????????????????????????????????????????
?              ?                               ?                                ?
?   update()   ?           Exception           ?     persists and reattaches    ?
?              ?                               ?                                ?
?????????????????????????????????????????????????????????????????????????????????
?              ?  copy the state of object in  ?    copy the state of obj in    ?
?    merge()   ?     DB, doesn't attach it,    ?      DB, doesn't attach it,    ?
?              ?    returns attached object    ?     returns attached object    ?
?????????????????????????????????????????????????????????????????????????????????
?              ?                               ?                                ?
?saveOrUpdate()?           as save()           ?            as update()         ?
?              ?                               ?                                ?
?????????????????????????????????????????????????????????????????????????????????



3> jrudolph..:

有关持久化和保存之间细微差别的解释,请参阅Hibernate论坛.看起来不同的是INSERT语句最终执行的时间.由于save确实返回了标识符,因此无论事务的状态如何(通常都是坏事),INSERT语句都必须立即执行.Persist不会为了分配标识符而在当前运行的事务之外执行任何语句.保存/保持两者都可以处理瞬态实例,即尚未分配标识符的实例,因此不会保存在数据库中.

更新合并都适用于分离的实例,即在DB中具有相应条目但当前未附加到会话(或由其管理)的实例.它们之间的区别是传递给函数的实例会发生什么.update尝试重新附加实例,这意味着现在可能没有附加到Session的持久实体的其他实例,否则抛出异常.但是,merge只是将所有值复制到Session中的持久化实例(如果当前未加载,将加载它).输入对象不会更改.因此,merge更新更通用,但可能会使用更多资源.



4> HakunaMatata..:

此链接以良好的方式解释:

http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/

我们都遇到了很少遇到的问题,当我们再次看到它们时,我们知道我们已经解决了这个问题,但却记不起来了.

在Hibernate中使用Session.saveOrUpdate()时抛出的NonUniqueObjectException是我的一个.我将为复杂的应用程序添加新功能.我所有的单元测试都运行良好.然后在测试UI时,尝试保存一个对象,我开始得到一个异常,消息"具有相同标识符值的另一个对象已经与会话相关联."这是来自Java Persistence with Hibernate的一些示例代码.

            Session session = sessionFactory1.openSession();
            Transaction tx = session.beginTransaction();
            Item item = (Item) session.get(Item.class, new Long(1234));
            tx.commit();
            session.close(); // end of first session, item is detached

            item.getId(); // The database identity is "1234"
            item.setDescription("my new description");
            Session session2 = sessionFactory.openSession();
            Transaction tx2 = session2.beginTransaction();
            Item item2 = (Item) session2.get(Item.class, new Long(1234));
            session2.update(item); // Throws NonUniqueObjectException
            tx2.commit();
            session2.close();

要了解此异常的原因,了解分离的对象以及在分离的对象上调用saveOrUpdate()(或只是update())时会发生什么很重要.

当我们关闭一个单独的Hibernate Session时,我们正在处理的持久对象被分离.这意味着数据仍然在应用程序的内存中,但Hibernate不再负责跟踪对象的更改.

如果我们然后修改我们的分离对象并想要更新它,我们必须重新附加该对象.在重新附加过程中,Hibernate将检查是否存在同一对象的任何其他副本.如果它找到了,它必须告诉我们它不知道"真正的"副本是什么了.也许对我们希望保存的其他副本进行了其他更改,但Hibernate不了解它们,因为它当时没有管理它们.

Hibernate不是保存可能不好的数据,而是通过NonUniqueObjectException告诉我们这个问题.

那么我们该怎么办呢?在Hibernate 3中,我们有merge()(在Hibernate 2中,使用saveOrUpdateCopy()).此方法将强制Hibernate将来自其他分离实例的任何更改复制到要保存的实例上,从而在保存之前合并内存中的所有更改.

        Session session = sessionFactory1.openSession();
        Transaction tx = session.beginTransaction();
        Item item = (Item) session.get(Item.class, new Long(1234));
        tx.commit();
        session.close(); // end of first session, item is detached

        item.getId(); // The database identity is "1234"
        item.setDescription("my new description");
        Session session2 = sessionFactory.openSession();
        Transaction tx2 = session2.beginTransaction();
        Item item2 = (Item) session2.get(Item.class, new Long(1234));
        Item item3 = session2.merge(item); // Success!
        tx2.commit();
        session2.close();

重要的是要注意merge返回对实例的新更新版本的引用.它不会将项目重新附加到会话.如果你测试实例相等(item == item3),你会发现在这种情况下它返回false.从这一点开始,您可能希望使用item3.

值得注意的是,Java Persistence API(JPA)没有分离和重新附加对象的概念,并使用EntityManager.persist()和EntityManager.merge().

我发现在使用Hibernate时,saveOrUpdate()通常足以满足我的需求.当我拥有可以引用相同类型对象的对象时,我通常只需要使用merge.最近,异常的原因在于代码验证引用不是递归的.作为验证的一部分,我正在将同一个对象加载到我的会话中,从而导致错误.

你在哪里遇到过这个问题?合并是否适用于您,或者您是否需要其他解决方案?您是否希望始终使用合并,或者仅在特定情况下根据需要使用合并



5> 小智..:

实际上,hibernate save()persist()方法之间的区别取决于我们正在使用的生成器类.

如果我们的生成器类被分配,那么save()persist(方法之间没有区别.因为生成器'已分配'意味着,作为程序员,我们需要将主键值保存在数据库中[希望您知道这个生成器概念]如果不是指定的生成器类,假设我们的生成器类名称是递增均值hibernate it self会将主键id值分配到数据库中[除了分配的生成器,hibernate只用于照顾主键id值记住],所以在这种情况下如果我们调用save()或者persist()方法那么它会将记录插入正常数据库但是听到的是, save()方法可以返回由hibernate生成的主键id值,我们可以看到它

long s = session.save(k);

在同样的情况下,persist()永远不会给客户任何价值.



6> OutOfMind..:

我找到了一个很好的例子,显示了所有hibernate保存方法之间的差异:

http://www.journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example

总之,根据以上链接:

保存()

我们可以在事务外调用此方法.如果我们在没有事务的情况下使用它,并且我们在实体之间进行级联,那么除非我们刷新会话,否则只保存主实体.

因此,如果从主对象映射了其他对象,则会在提交事务或刷新会话时保存它们.

坚持()

它类似于在事务中使用save(),因此它是安全的并且可以处理任何级联对象.

saveOrUpdate()方法

可以在有或没有事务的情况下使用,就像save()一样,如果它在没有事务的情况下使用,映射的实体将不会被保存为un; ess我们刷新会话.

根据提供的数据生成插入或更新查询的结果.如果数据存在于数据库中,则执行更新查询.

更新()

当我们知道我们只更新实体信息时,应该使用Hibernate更新.此操作将实体对象添加到持久上下文,并在提交事务时跟踪和保存进一步的更改.

因此,即使在调用update之后,如果我们在实体中设置任何值,它们将在事务提交时更新.

合并()

Hibernate merge可用于更新现有值,但此方法从传递的实体对象创建副本并返回它.返回的对象是持久化上下文的一部分,并跟踪任何更改,不跟踪传递的对象.这是与所有其他方法的merge()的主要区别.

另外,对于所有这些的实际例子,请参考我上面提到的链接,它显示了所有这些不同方法的示例.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有