hibernate持久化方法“在事务之外调用”的含义

时间:2015-09-04 19:50:04

标签: hibernate transactions

  

persist()使瞬态实例持久化。但事实并非如此   保证将标识符值分配给持久性   实例立即,分配可能发生在刷新时。   persist()还保证它不会执行INSERT语句   如果在事务边界之外调用它。这很有用   长时间运行的会话与扩展的会话/持久性   上下文。

这一行" persist()还保证如果在事务边界之外调用它,它将不会执行INSERT语句。"似乎令人困惑。如果我们调用了persist(),那么它已经是会话的一部分了。那为什么交易之外的问题"到达?

1 个答案:

答案 0 :(得分:0)

在特殊情况下,您可以在事务之外调用persist(),例如,如果您使用的是扩展类型持久性上下文。在购买应用时考虑这种情况:

您已定义EntityManager扩展类型

@PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;

您有一个方法,可以在用户创建新订单时创建Order

// this method is called outside transaction
public void createOrder() {
   this.order = new Order();
   em.persist(order); //the entity is not flushed to the database, but rather remain managed by the entity manager
}

当用户开始添加要包含在订单中的项目时,您会将Item添加到Order实体。

// this method is also called outside transaction and can be called as many as items added by user
public void addOrderItems(Item item) {
   em.persist(item);// also not flushed to the database, but rather remain managed by the entity manager
   this.order.getItems().add(item);
   item.setOrder(this.order);
}

每当用户完成订单后,完成订单处理将执行此方法

// this is where the transaction started
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public void completeOrder() {
   em.flush();
}

因为现在我们有了一个事务,所以实体将被插入到数据库中。

换句话说,所有persist()个操作都排队,当有事务时,队列就会被执行。