Java 在Hibernate中使用lazy属性
hibernate中property标记的lazy属性允许按照以下链接延迟加载属性: lazy(可选-默认为false):指定此属性 应该在第一次访问实例变量时延迟获取。 它需要构建时字节码插装 但是,当我尝试为我的一个属性设置lazy=true时,在本例中,它并没有延迟加载: 休眠映射文件:Java 在Hibernate中使用lazy属性,java,hibernate,orm,properties,lazy-loading,Java,Hibernate,Orm,Properties,Lazy Loading,hibernate中property标记的lazy属性允许按照以下链接延迟加载属性: lazy(可选-默认为false):指定此属性 应该在第一次访问实例变量时延迟获取。 它需要构建时字节码插装 但是,当我尝试为我的一个属性设置lazy=true时,在本例中,它并没有延迟加载: 休眠映射文件: <hibernate-mapping package="org.hibernate.tutorial.domain"> <class name="Event" table="E
<hibernate-mapping package="org.hibernate.tutorial.domain">
<class name="Event" table="EVENTS" select-before-update="true">
<id name="id" column="EVENT_ID">
<generator class="native" />
</id>
<property name="date" type="timestamp" column="EVENT_DATE" />
<property name="title" lazy="true"/>
<set name="participants" table="PERSON_EVENT" inverse="true">
<key column="EVENT_ID" />
<many-to-many column="PERSON_ID" class="Person" />
</set>
</class>
</hibernate-mapping>
由hibernate生成的查询:
Hibernate: select event0_.EVENT_ID as EVENT1_0_0_, event0_.EVENT_DATE as EVENT2_0_0_, event0_.title as title0_0_ from EVENTS event0_ where event0_.EVENT_ID=?
请帮助我理解为什么在这种情况下懒惰不起作用?懒惰加载只是对持久性提供程序的一个提示。此提示不保证实体将实际被延迟加载 如果提供者认为这是一种更好的方法,那么提供者可以自由地急切地加载它们 特别是基本属性很少会被延迟加载,因为延迟加载不会提高性能,相反 行为可能因上下文而异,因此不可能可靠地测试延迟加载。另一方面,即时加载(默认)是有保证的,并且可以对其进行测试
编辑如果您只想查看延迟加载的效果-当延迟加载的属性与其他实体或LOB相关时,更可能发生延迟加载 您使用的延迟加载
不是正确的使用方法,因为标题与其他对象没有关联。如果在您的关系映射中使用它,那么它将给您带来一些性能提升
在上述配置中。如果lazy=“false”
:-加载事件对象时,也会加载子对象Person并将其设置为setPerson()方法。如果调用evet.getPerson()
,则加载的数据将返回。没有新的数据库调用
如果lazy=“true”
:-这是默认配置。如果你没有提到,那么休眠考虑<代码>懒惰=真< /代码>。加载事件
对象时,未加载子对象Person。您需要额外调用数据库以获取地址对象。如果调用event.getPerson()
,则此时数据库查询将激发并返回结果。刷新数据库调用
要测试一次,请将其设置为false,然后使用Hibernate 5查看输出查询
首先,您需要添加以下Maven插件:
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>${hibernate.version}</version>
<executions>
<execution>
<configuration>
<enableLazyInitialization>true</enableLazyInitialization>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
获取实体时:
Event event = entityManager.find(Event.class,
eventHolder.get().getId());
LOGGER.debug("Fetched event");
assertEquals("Cluj-Napoca", event.getLocation().getCity());
Hibernate将使用辅助选择加载lazy属性:
SELECT e.id AS id1_0_0_
FROM event e
WHERE e.id = 1
-- Fetched event
SELECT e.location AS location2_0_
FROM event e
WHERE e.id = 1
在我的项目中,我有证据表明,通过
ScrollableResult
在1M+个实体上加载一个VARCHAR(255)列可以极大地提高性能。因此,有时需要延迟加载基本属性。只要持久性提供程序接受提示并相应地修改SQL查询,这是有意义的。我已经根据专业JPA2书提出了我的建议。它建议不要在基本道具上延迟加载,可能是因为持久性提供程序在编写本书时没有修改SQL。您是否记录了JPA在有无延迟提示的情况下发出的查询?一些细节会很有趣的。弗拉德,没有梅文能做到吗?Maven在我们公司被禁止:-(我也尝试过使用hibernate.enhance.enable
属性,但没有resultHibernate也提供用于构建时检测的Gradle插件。但是,您也可以使用。这假设您使用EntityManager API而不是SessionFactory,对吗?我在hibernate代码中看到,在运行时也可以使用prop进行检测但是代码只在EntityManager Factory中引用这对EntityManager Factory或SessionFactory都有效。这没关系。只是JPA/Hibernate实体被检测了。之后,EMF或SF.Hmmm会这样使用它们。我不确定。我的意思是,从您提供的链接来看,我似乎必须使用EntityManager来使用它们运行时插装。在我的项目中,对于根本性的更改已经非常成熟,我们使用SessionFactory。因此,我尝试将hibernate.enhancer.enableLazyInitialization
设置到我的SessionFactory中,没有结果。查看代码,该代码似乎只在EM部分引用。我有一个问题,我将尽快对其进行编辑n最新发现。谢谢
Event event = entityManager.find(Event.class,
eventHolder.get().getId());
LOGGER.debug("Fetched event");
assertEquals("Cluj-Napoca", event.getLocation().getCity());
SELECT e.id AS id1_0_0_
FROM event e
WHERE e.id = 1
-- Fetched event
SELECT e.location AS location2_0_
FROM event e
WHERE e.id = 1