我以base教程项目(链接) >本机引导>注释示例为例。
Hibernate版本: 5.4.29
实体:
@Entity
public class Customer {
@Id
@GeneratedValue
private Integer id;
private String name;
@Basic( fetch = FetchType.LAZY )
private UUID accountsPayableXrefId;
@Lob
@Basic( fetch = FetchType.LAZY )
@LazyGroup( "lobs" )
private Blob image;
// getters and setters
}在hibernate.cfg.xml中,我添加了以下行
<property name="hibernate.enhancer.enableLazyInitialization">true</property>单元测试
public void testLazy() throws SerialException, SQLException {
Session session = sessionFactory.openSession();
session.beginTransaction();
byte[] bytes = "A byte array".getBytes();
Blob blob = new javax.sql.rowset.serial.SerialBlob(bytes);
Customer customer = new Customer();
customer.setName("John Doe");
customer.setAccountsPayableXrefId(UUID.randomUUID());
customer.setImage(blob);
session.save( customer );
Integer id = customer.getId();
session.getTransaction().commit();
session.close();
session = sessionFactory.openSession();
session.beginTransaction();
Customer found = session.find(Customer.class, id);
System.out.println("Customer: " + found.getAccountsPayableXrefId());
System.out.println("Customer: " + found.getImage().length());
session.getTransaction().commit();
session.close();
}我希望在实体提取字段中标记为lazy的字段甚至不会从DB中被选中,直到显式引用它们,但我在日志中看到:
Hibernate: select customer0_.id as id1_0_0_, customer0_.accountsPayableXrefId as accounts2_0_0_, customer0_.image as image3_0_0_, customer0_.name as name4_0_0_ from Customer customer0_ where customer0_.id=?查询提供了相同的结果(懒惰= false)
List<Customer> result = session.createQuery( "from Customer" ).list();
for ( Customer c : result ) {
System.out.println("Customer: " + c.getAccountsPayableXrefId());
System.out.println("Customer: " + c.getImage().length());
}在跟踪日志中有这样的行
[2021-03-17 20:44:10.349][][DBG][org.hibernate.cfg.Ejb3Column][main] Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Customer), mappingColumn=accountsPayableXrefId, insertable=true, updatable=true, unique=false}
[2021-03-17 20:44:10.349][][DBG][org.hibernate.cfg.annotations.PropertyBinder][main] MetadataSourceProcessor **property accountsPayableXrefId with lazy=true**
...
[2021-03-17 20:44:10.351][][DBG][org.hibernate.cfg.annotations.PropertyBinder][main] MetadataSourceProcessor property image with lazy=true
...
[2021-03-17 20:44:10.461][][DBG][org.hibernate.internal.SessionFactoryImpl][main] Instantiating session factory with properties: {... hibernate.enhancer.enableLazyInitialization=true}
...
[... 20:44:11.382][][TRC][o.h.event.internal.DefaultLoadEventListener][main] Loading entity: [o.h.tutorial.annotations.Customer#1]
[... 20:44:11.384][][TRC][o.h.persister.entity.AbstractEntityPersister][main] Fetching entity: [o.h.tutorial.annotations.Customer#1]
[... 20:44:11.386][][DBG][o.h.SQL][main] select customer0_.id as id1_0_0_, customer0_.accountsPayableXrefId as accounts2_0_0_, customer0_.image as image3_0_0_, customer0_.name as name4_0_0_ from Customer customer0_ where customer0_.id=?
[... 20:44:11.387][][TRC][o.h.type.descriptor.sql.BasicBinder][main] binding parameter [1] as [INTEGER] - [1]
[... 20:44:11.457][][TRC][o.h.loader.plan.exec.process.internal.EntityReferenceInitializerImpl][main] hydrating entity state
[... 20:44:11.459][][TRC][o.h.persister.entity.AbstractEntityPersister][main] Hydrating entity: [o.h.tutorial.annotations.Customer#1]
[... 20:44:11.460][][TRC][o.h.type.descriptor.sql.BasicExtractor][main] extracted value ([accounts2_0_0_] : [BINARY]) - [a897b3c2-c19c-4f36-b0a1-17bca893f433]
[... 20:44:11.464][][TRC][o.h.type.descriptor.sql.BasicExtractor][main] extracted value ([image3_0_0_] : [BLOB]) - [{blob}]
[... 20:44:11.465][][TRC][o.h.type.descriptor.sql.BasicExtractor][main] extracted value ([name4_0_0_] : [VARCHAR]) - [John Doe]
[... 20:44:11.466][][TRC][o.h.loader.plan.exec.process.internal.AbstractRowReader][main] Total objects hydrated: 1
[... 20:44:11.467][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Resolving attributes for [o.h.tutorial.annotations.Customer#1]
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Processing attribute `accountsPayableXrefId` : value = a897b3c2-c19c-4f36-b0a1-17bca893f433
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Attribute (`accountsPayableXrefId`) - enhanced for lazy-loading? - false
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Processing attribute `image` : value = blob0: X'412062797465206172726179'
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Attribute (`image`) - enhanced for lazy-loading? - false
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Processing attribute `name` : value = John Doe
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Attribute (`name`) - enhanced for lazy-loading? - false
[... 20:44:11.468][][DBG][o.h.engine.internal.TwoPhaseLoad][main] Done materializing entity [o.h.tutorial.annotations.Customer#1] 所以看起来懒散加载对我的例子不起作用。我做错什么了?
发布于 2021-06-08 17:05:03
尝试使用“域模型的构建时增强”而不是运行时。设置更简单,效率更高,因为在编译过程中更改了实体的字节码:
<build>
<plugins>
[...]
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>${hibernate.version}</version>
<executions>
<execution>
<configuration>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</plugins>
</build>之后,在实体类中,您可以使用@Basic( fetch = FetchType.LAZY )注释来加载延迟列:
@Entity
public class Customer {
@Id
@GeneratedValue
private Integer id;
private String name;
@Basic( fetch = FetchType.LAZY )
private UUID accountsPayableXrefId;
@Basic( fetch = FetchType.LAZY )
private Blob image;
// getters and setters
}若要验证,请将SQL添加到application.yaml文件中:
spring:
jpa:
properties:
hibernate.show_sql: true
hibernate.format_sql: true
logging:
level:
org.hibernate.type.descriptor.sql.BasicBinder: TRACE并使用maven构建应用程序,因为如果尝试从IntelliJ或Eclipse中运行该插件,则不会调用该插件:
./mvnw clean spring-boot:runhttps://stackoverflow.com/questions/66681126
复制相似问题