gpt4 book ai didi

hibernate - 努力了解EntityManager的正确使用

转载 作者:行者123 更新时间:2023-12-04 13:32:19 28 4
gpt4 key购买 nike

我正在开始一个新项目,并且对JPA/Hibernate的使用是全新的。我试图了解如何正确使用EntityManager。更准确地说,何时实例化它们,我需要多少个,我应该关闭它们,我应该将所有东西都放入交易中吗?

无论如何,在我当前的代码中,尝试读取以前保存的实体时,出现了org.hibernate.LazyInitializationException异常。我会理解相反的情况(在事务中读取一个实体,然后尝试将读取的实体保存在另一个事务中,但是由于事务结束,该实体不受管理,所以保存失败),但是我无法理解。

我将代码放在GitHub(https://github.com/GaetanLeu/intl)上,这只是几个类。我的主目录位于src/sandbox/MessageSandbox.java中,它在第28行失败,并带有以下stacktrace:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at entity.MessageKey_$$_jvstfcc_0.toString(MessageKey_$$_jvstfcc_0.java)
at java.lang.String.valueOf(String.java:2854)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at com.google.common.base.Present.toString(Present.java:88)
at java.lang.String.valueOf(String.java:2854)
at java.io.PrintStream.println(PrintStream.java:821)
at sandbox.MessageSandbox.main(MessageSandbox.java:28)

另外,我从Hibernate收到警告,说我的EntityManager已经存在,然后会发生什么? EntityManagerFactory.createEntityManager方法是否返回现有方法?
WARN: HHH000436: Entity manager factory name (intl) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'

确实我不知道何时创建EntityManagers ^^任何帮助将不胜感激,但是请简单说明一下,我对此确实很陌生。

哦,顺便说一句,我想精确地说,我没有使用Spring,没有EJB,我想暂时手动操作EntityManager,直到我理解为止。谢谢 :)

最佳答案

一个entityManager管理一个persistence context,换句话说,一个数据库状态的内存快照。

参见What is a persistence object?

使用entityManager加载的每个对象都将处于托管状态(请参见entity life cycle),直到您关闭EM。当一个实体是managed时,将跟踪对其所做的所有更改,然后在刷新EM时将其持久化。将自动触发一个请求以动态加载数据,但是如果实体处于分离状态(如果EM已关闭),则访问惰性属性将导致错误。

EM的范围(/生命周期)取决于您的执行上下文。例如,对于Web应用程序,通常将为每个http请求创建一个EM。

对于独立的应用程序,您必须注意是否可以通过另一个应用程序/线程更新数据库。如果可以,您的持久性上下文可能与数据库状态不一致,因此应为每个工作单元(事务)创建该上下文以避免这种情况。否则,您可以为所有应用程序生命周期创建一个实例,然后定期刷新它。

对于CRUD应用程序,其生命周期通常如下:

  • 创建EM
  • 获取某些实体(它们受到如此管理,对惰性属性的任何访问都会从DB加载数据)
  • 关闭EM(实体现已分离,对lazy属性的任何访问都会导致LazyInitializationException)
  • 向用户显示数据

  • 在用户更新验证中:
  • 创建em
  • 开一个交易
  • 合并(附加)您更新后的实体(这就是您所谓的保存)(如果您设置了一些光学锁定,则em将在此处根据数据库检查实体版本)
  • 最终执行一些业务验证或其他更新
  • 提交事务并关闭em(更改将被刷新)

  • 请记住,EM是轻量级的对象,创建和销毁它们的代价很低,并且没有线程安全性。

    顺便说一句,JPA是Java EE规范,它是EJB规范的一部分(持久性部分)。其目的是在Java EE容器上下文(自JEE 6开始的Java EE应用程序服务器或CDI)中使用。您仍然可以通过JPA合约在独立模式下使用 hibernate 模式,但是即使在这种情况下,也必须考虑与spring耦合以利用容器管理的功能。

    关于hibernate - 努力了解EntityManager的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22772980/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com