首页 文章

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

提问于
浏览 119 次
2

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

我应该在Session上使用persist()吗? Hibernate Session接口还具有persist()方法 . 它具有与JPA的persist()操作相同的语义 . 但是,这两项操作在冲洗方面存在重要差异 . 在同步期间,即使您使用此选项映射关联,Hibernate会话也不会将persist()操作级联到关联的实体和集合 . 它只与您调用persist()时可访问的实体级联!如果使用Session API,则只有save()(和update())在刷新时级联 . 然而,在JPA应用程序中,它是相反的:只有persist()在刷新时级联 .

这种难以辨认的措辞......这意味着“当你打电话给坚持()时可以到达的实体”?

如果我更新了一个关联的实体,那么它是否应该“可达”?

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

2 回答

  • 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之间应该没有任何区别 .

    它只能级联到调用persist()时可以访问的实体!

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

    您也可以使用persist()而不是save(),并使用EJB3 >>早期草稿中定义的语义 .

    但根据文件:

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

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

    那时,持久的JPA定义只是一个草案,因此特定的实现并没有反映出明确的特征 .

  • 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) 时,该行无法从订单中获得't be persisted, because it':此时,该行尚未在订单中 .

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

    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
    

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

相关问题