4.10. bytecode 增强
字节代码增强用于处理类的字节代码(.class)表示,用于出于某些目的处理类的字节代码(.class)表示,如添加与持久性相关的功能。对于 JBoss EAP 实例,您可以在运行时执行字节代码增强。
JBoss EAP 不支持并测试构建时间字节代码增强。
域模型的运行时增强只在管理的 JPA 环境中被支持,因为它使用 JPA 定义的服务提供商接口(SPI)来执行类转换。默认禁用运行时增强。
要启用运行时增强,请根据您的要求在持久性单元中设置以下属性的值:
-
enableLazyInitialization:在需要 lazy 属性加载时启用此属性。 -
enableDirtyTracking:在需要 self-dirty 跟踪的增强时启用此属性。 -
enableAssociationManagement:当需要增强双向关联管理时启用此属性。
示例:设置启用运行时增强的属性
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="Example">
...
<properties>
<property name="hibernate.enhancer.enableLazyInitialization" value="true" />
<property name="hibernate.enhancer.enableDirtyTracking" value="true" />
<property name="hibernate.enhancer.enableAssociationManagement" value="true" />
...
</properties>
</persistence-unit>
</persistence>
只有注解的类才能获得运行时增强支持。这意味着,只有永久单元中声明的类才会得到增强。
4.10.1. lazy Attribute Loading 复制链接链接已复制到粘贴板!
lazy 属性加载是一种字节码增强,它允许您告知 Hibernate,从数据库获取时仅应加载实体的特定部分,以及应在何时加载其他剩余部分。这与基于代理加载的理念不同,后者是实体中心,即在需要时一次性加载实体的状态。通过字节码增强,根据需要加载各个属性或属性组。
可以将 lazy 属性指定为一起加载,这称为 lazy 组。默认情况下,所有单数属性都是单个组的一部分。访问一个 lazy singular 属性时,会加载所有 lazy 单数属性。与单片组不同,lazy 复数属性是各个离散的 lazy 组。此行为可通过 @org.hibernate.annotations.LazyGroup 注释显式控制。
@Entity
public class Customer {
@Id
private Integer id;
private String name;
@Basic( fetch = FetchType.LAZY )
private UUID accountsPayableXrefId;
@Lob
@Basic( fetch = FetchType.LAZY )
@LazyGroup( "lobs" )
private Blob image;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UUID getAccountsPayableXrefId() {
return accountsPayableXrefId;
}
public void setAccountsPayableXrefId(UUID accountsPayableXrefId) {
this.accountsPayableXrefId = accountsPayableXrefId;
}
public Blob getImage() {
return image;
}
public void setImage(Blob image) {
this.image = image;
}
}
在上例中,有两个 lazy 属性:accounts PayableXrefId 和 image。这些属性各自属于不同的获取组。accountsPayableXrefId 属性是默认 fetch 组的一部分,这意味着访问 accountsPayableXrefId 不会强制加载 映像 属性,反之亦然。
4.10.2. In-line dirty tracking 复制链接链接已复制到粘贴板!
Hibernate 支持基于差异的跟踪计算来确定持久性上下文中已更改的实体。这意味着 Hibernate 会针对实体的最后已知状态检查实体的当前状态,以跟踪任何更改。
in-line dirty 跟踪功能可用于跟踪可以更改其内部状态的数据类型,而无需执行 state-difference 计算。Hibernate 操控您的类字节码,直接向实体添加脏跟踪功能,使实体能够跟踪已更改的属性。
4.10.3. 双向关联管理 复制链接链接已复制到粘贴板!
Hibernate 有助于开发符合 Java 语言约定的应用程序。
以下示例显示了不正确的 Java 用法:
示例:不正确的 Java 使用量
Order order = new Order();
LineItem lineItem = new LineItem();
order.getLineItems().add( lineItem );
// This blows up (NPE) in normal Java usage
lineItem.getOrder.getname();
以下示例显示了正确的 Java 用法:
示例:修正 Java 用法
Order order = new Order();
LineItem lineItem = new LineItem();
order.getLineItems().add( lineItem );
lineItem.setOrder( order );
// Now this is OK...
lineItem.getOrder.getname();
双向关联管理功能允许在操作方时进行双向关联。