当前位置: 首页 > 知识库问答 >
问题:

Hibernate会话。persist()与JPA entityManager。持久化()

司马辉
2023-03-14

摘自Java Persistence with Hibernate(Manning,2007)第419页:

我应该在会话上使用持久化()吗?Hibernate会话接口还具有一个持久化()方法。它与JPA的持久化()操作具有相同的语义学。但是,这两种操作在刷新方面有一个重要的区别。在同步期间,Hibernate会话不会将持久化()操作级联到关联的实体和集合,即使您使用此选项映射了关联。它只级联到调用持久化()时可访问的实体!如果您使用会话API,则只有保存()(和更新())在刷新时级联。然而,在JPA应用程序中,情况正好相反:只有持久化()在刷新时级联。

如此难以辨认的措辞。。。“调用persist()时可以访问的实体”是什么意思?

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

而且如果它是会话行为的一部分。persist(),那么为什么它不在javadoc中呢?

共有2个答案

闻人昊昊
2023-03-14

我真的不知道这是不是真的,但我至少可以解释一下这意味着什么。

假设您有以下实体:

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

根据您问题中的文本,该行不会被持久化,因为当调用持久化(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

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

丌官承
2023-03-14

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。冬眠内部的一场持久化(实体)。

所以,在持久化实体方面,JPA和Hibernate应该没有任何区别。

它仅级联到当您调用持久化()时可访问的实体!

2007年,Hibernate 3.2已经发布,3.3版本即将发布。当时,JPA只是一份草案:

您还可以使用persist()而不是save(),其语义在EJB3中定义

但根据文件:

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

对于JPA来说,级联持久化()是有意义的,因为根本没有保存()操作。但当时人们使用的是保存()、saveOrUpadet()甚至saveOrUpdateCopy(),它们被弃用以支持持久化()和合并()。

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

 类似资料:
  • 问题内容: 在CentOS 6.3上与Python 2.7,Apache + mod_wsgi一起运行 当我在localhost上时,一切正常。但是,当我在Azure中的vm上运行代码时,我看不到会话信息在页面之间保留。 基本上我的看法是: 打印输出为: 我对apache的wsgi配置是: 我设置了secret_key: 我尝试同时设置SERVER_NAME,但这无济于事: 关于如何进行更多调试的

  • 问题内容: 我正在使用请求模块(Python 2.5的版本0.10.0)。我已经弄清楚了如何将数据提交到网站上的登录表单并检索会话密钥,但是我看不到在后续请求中使用此会话密钥的明显方法。有人可以在下面的代码中填写省略号还是建议其他方法? 问题答案: 您可以使用以下方法轻松创建持久会话: 之后,请继续执行您的请求: 有关会话的更多信息,请访问:https : //requests.kennethre

  • 我有一个与CRUD能力的平均应用程序完全测试与邮递员。我一直试图坚持登录相当长的一段时间,现在没有运气。我已经阅读并尝试了以下内容 护照文档 Toon Io关于登录的博客 快速会话 苏格兰io,节点auth容易 加上一些其他简单的阅读材料(很多这样的问题) 但是我只能注册和登录一个用户,不能用会话持久登录。 下面是我对用户登录的理解,包括我的项目中的代码示例和邮递员结果的截图以及控制台日志。 我有

  • 我对Hibernate中的会话和事务的概念有点困惑。据我所知,Hibernate使用会话(持久性上下文),它基本上是需要持久,删除或数据库中任何内容的实体的缓存。会话封装事务,因此我启动一个会话,然后创建一个事务。事务关闭后,持久性上下文中的所有内容都将刷新到数据库,如果我关闭会话,也会发生同样的事情。 为什么我需要两者?我可以在不创建交易的情况下做同样的事情吗?

  • 持久化类(Persistent Object )简称 PO,在 Hibernate 中, PO 是由 POJO(即 java 类或实体类)和 hbm 映射配置组成。 简单点说,持久化类本质上就是一个与数据库表建立了映射关系的普通 Java 类(实体类),例如 User 类与数据库中 user 表通过映射文件 User.hbm.xml 建立了映射关系,此时 User 就是一个持久化类。 持久化类的规

  • 问题内容: 我正在尝试实现一个简单的DAO。我有道: 和一个实体: 这是appContext.xml: 除非我在之后调用或插入未执行。这是为什么?如果删除,则刷新时会出现“没有正在进行的事务”的错误,但是如果删除刷新,则不会插入到数据库中。 问题答案: 之所以这样工作是因为您使用标记了事务为只读。 如您所见,由于您仍然可以通过手动调用保留更改,因此它不会使您的事务实际上是只读的。但是,它在事务结束