Hibernate session.persist()vs JPA entityManager.persist()

时间:2014-07-07 18:29:06

标签: hibernate jpa

来自Java Persistence with Hibernate(Manning,2007)p。 419:

  

我应该在Session上使用persist()吗? Hibernate Session接口   还有一个persist()方法。它具有与之相同的语义   JPA的persist()操作。但是,有一个重要的区别   关于冲洗的两个操作之间。中   同步,Hibernate Session不会级联persist()   对相关实体和集合的操作,即使您已映射   与此选项的关联。 它只与实体级联   当你调用persist()时可以访问!只有save()(和update())   如果使用Session API,则在刷新时级联。在JPA中   然而,应用程序是相反的:只有persist()才是   在冲洗时级联。

这种难以理解的措辞......这意味着“当你呼叫坚持时可以到达的实体()”是什么意思?

如果我更新了关联实体,那么它是否应该“无法访问”?

另外......如果它是session.persist()行为的一部分,那为什么它不在javadoc

2 个答案:

答案 0 :(得分:0)

我真的不知道这是不是真的,但我至少可以解释它的含义。

假设您有以下实体:

public class Order {
    @OneToMany(cascade = PERSIST)
    private List<OrderLine> lines;
    // ...
}

并执行以下操作:

Order order = new Order();
session.persist(order);
OrderLine line = new OrderLine();
order.addLine(line);
session.flush(); // the flush could also be called implicitely, when committing or executing a query

根据您问题中的文字,该行不会被保留,因为调用persist(order)时订单无法访问:此时,该行不在订单呢。

另一方面,您是否使用实体管理器:

Order order = new Order();
em.persist(order);
OrderLine line = new OrderLine();
order.addLine(line);
em.flush(); // the flush could also be called implicitely, when committing or executing a query

然后该行将被保留,因为当实体的状态与数据库同步时,它可以从刷新时的订单到达。

答案 1 :(得分:0)

Hibernate的EntityManager实现是:

org\hibernate\hibernate-entitymanager\4.3.5.Final\hibernate-entitymanager-4.3.5.Final-sources.jar!\org\hibernate\jpa\spi\AbstractEntityManagerImpl.java

这是persist()方法

@Override
public void persist(Object entity) {
    checkOpen();
    try {
        internalGetSession().persist( entity );
    }
    catch ( MappingException e ) {
        throw convert( new IllegalArgumentException( e.getMessage() ) ) ;
    }
    catch ( RuntimeException e ) {
        throw convert( e );
    }
}

所以JPA persist(实体)实际上是在调用org.hibernate.internal.Session.persist(entity)。

因此,在持久化实体方面,JPA和Hibernate之间不应该有任何区别。

  

它只与您通话时可以访问的实体级联   坚持()!

2007年,Hibernate 3.2已经发布,3.3版本正在发布。那时候JPA was only a draft

  

您也可以使用persist()而不是save(),并使用EJB3中定义的语义&gt; &GT; &GT;提前选秀。

但根据文件:

  

如果将父级传递给persist(),则会传递所有子级   坚持()

对于JPA,级联persist()是有意义的,因为根本没有save()操作。但当时人们正在使用save(),saveOrUpadet()甚至saveOrUpdateCopy(),这些都被弃用,而选择了persist()和merge()。

当时,持久的JPA定义只是一个草案,因此特定的实现并未反映出明确的特征。