【问题标题】:Persist new JPA entity and detach保留新的 JPA 实体并分离
【发布时间】:2017-06-05 02:56:36
【问题描述】:

用例是:

  • 创建大量新实体并将它们保存在数据库中的单个事务中

我能找到使用 JPA/Hibernate 的唯一有效解决方案是执行以下步骤。原因是休眠将实体保留在一级缓存中直到事务结束。

  • 创建一个新实体
  • 强制快速刷新()
  • 分离实体

这样做的开销是

  • 您需要将 entityManager/sessionFactory 注入业务逻辑,并管理实体的刷新和分离
  • 您需要在每次插入后强制进行低效冲洗

真正的期望是 JPA 或至少 Hibernate 会公开某种功能以快速创建实体并在不对其进行管理的情况下将其持久化。

其他解决方案:

  • 使用 JDBC 或 JdbcTemplate,但您必须为实体编写自己的插入操作

所以问题是:是否有可能同时保持和分离,或者更好地保持而不被管理?

【问题讨论】:

标签: hibernate jpa spring-data-jpa


【解决方案1】:

您可以使用没有一级缓存的无状态会话。 来自文档:

 StatelessSession session = sessionFactory.openStatelessSession();
 Transaction tx = session.beginTransaction();
 ScrollableResults customers = session.getNamedQuery("GetCustomers")
        .scroll(ScrollMode.FORWARD_ONLY);
 while ( customers.next() ) {
     Customer customer = (Customer) customers.get(0);
     customer.updateStuff(...);
     session.update(customer);
 }     
 tx.commit();
 session.close();

在此代码示例中,查询返回的 Customer 实例是 立即分离。它们从不与任何持久性相关联 上下文。

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html

【讨论】:

  • 不幸的是我需要在一个事务中,要么全部要么什么都没有
  • 那没问题,上述解决方案如何阻止您这样做?
  • 我认为 StatelessSession 不能存在于事务中
  • 我认为这无关紧要,无论哪种方式交易都有效。我个人使用StatelessSession 仅用于“轻量级查询”,但上面的示例来自 Hibernate Docs,因此它应该可以工作。如果您使用 Spring 的声明式事务,@Transactional(rollbackFor = Exception.class) 或您的自定义异常,一切都应该很好。
猜你喜欢
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
相关资源
最近更新 更多