【问题标题】:Is it possible to detach Hibernate entity, so that changes to object are not automatically saved to database?是否可以分离 Hibernate 实体,以便对对象的更改不会自动保存到数据库?
【发布时间】:2011-08-13 15:15:59
【问题描述】:

我有 Hibernate 实体,我必须转换为 JSON,我必须翻译实体中的一些值,但是当我翻译值时,这些值会立即保存到数据库中,但我不想将这些更改保存到数据库。这个问题有解决办法吗?

【问题讨论】:

    标签: java hibernate persistence


    【解决方案1】:

    就我而言,我只是刷新并清除了会话。

    session.flush(); session.clear();

    【讨论】:

      【解决方案2】:
      public static <E> E deepClone(E e) {
          ByteArrayOutputStream bo = new ByteArrayOutputStream();
          ObjectOutputStream oo;
          try {
              oo = new ObjectOutputStream(bo);
              oo.writeObject(e);
          } catch (IOException ex) {
              ex.printStackTrace();
          }
          ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
          ObjectInputStream oi;
          try {
              oi = new ObjectInputStream(bi);
              return (E) (oi.readObject());
          } catch (IOException ex) {
              ex.printStackTrace();
              return null;
          } catch (ClassNotFoundException ex) {
              ex.printStackTrace();
              return null;
          }
      }
      

      首先:deepClone 会话 pojo
      第二:更改字段
      然后:做任何你想做的事

      【讨论】:

        【解决方案3】:

        您还可以通过使用StatelessSession 来避免将您的实体附加到休眠会话:

        StatelessSession session = sessionFactory.openStatelessSession();
        

        而不是

        Session session = sessionFactory.getCurrentSession();
        

        请注意,与常规 Hibernate Session 不同,您必须小心关闭 StatelessSession

        session.close(); // do this after you are done with the session
        

        与常规 Session 相比的另一个区别是 StatelessSession 无法获取集合。我看到它的主要目的是仅获取数据 SQLQuery 的东西。

        您可以在此处阅读有关不同会话类型的更多信息:

        http://www.interviewadda.com/difference-between-getcurrentsession-opensession-and-openstatelesssession/

        【讨论】:

          【解决方案4】:

          我还将休眠实体转换为 JSON。

          当你关闭会话时你不能延迟加载对象。因此,您可以使用

          hSession.setDefaultReadOnly(true);
          

          并在完成 JSON 后关闭会话。

          【讨论】:

            【解决方案5】:

            您可以通过调用Session.evict() 来分离实体。

            其他选项是在转换值之前创建实体的防御性副本,或者使用 DTO 代替该代码中的实体。我认为这些选项更优雅,因为它们不会耦合到 JSON 和持久层的转换。

            【讨论】:

            • 如果是JPA,可以使用:EntityManager.detach(object)
            • 我一直为此使用 DTO。使用防御性副本是个好主意,但随着时间的推移,维护变得更加困难,人们认为新对象是托管对象,但实际上它实际上是本地副本。
            【解决方案6】:

            关闭会话。这将为您分离您的实体,并且不会刷新任何修改。如果那不可能,请考虑禁用 autoFlush ......但那是另外一罐蠕虫。最简单的方法是关闭 Session 并完成它!

            【讨论】:

              猜你喜欢
              • 2023-03-18
              • 2012-07-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-04-16
              • 1970-01-01
              相关资源
              最近更新 更多