4.1版本将新增一个实际API,用于通过natural id加载实体。是的,之前的版本通过使用criteria查询实现了natural id加载,但这种方法非常有限。新的API将允许在Session和SessionFactory级别进行缓存,并提供一致的API。为了保持一致性,新的方法也适用于基于标识符的加载。
作为起点,Session合同中已添加了新方法(请参阅源代码或javadoc以获取更多讨论)
public IdentifierLoadAccess byId(String entityName); public IdentifierLoadAccess byId(Class entityClass); public NaturalIdLoadAccess byNaturalId(String entityName); public NaturalIdLoadAccess byNaturalId(Class entityClass); public SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName); public SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass);
所有加载访问代理都有获取实体引用的方法(getReference)和加载实体的方法(load)。这种区别类似于Session中的旧版get和load方法;getReference在加载访问代理上等于Session.load和load在加载访问代理上等于Session.get
public interface IdentifierLoadAccess { public IdentifierLoadAccess with(LockOptions lockOptions); public Object getReference(Serializable id); public Object load(Serializable id); } public interface NaturalIdLoadAccess { public NaturalIdLoadAccess with(LockOptions lockOptions); public NaturalIdLoadAccess using(String attributeName, Object value); public Object getReference(); public Object load(); } public interface SimpleNaturalIdLoadAccess { public SimpleNaturalIdLoadAccess with(LockOptions lockOptions); public Object getReference(Object naturalIdValue); public Object load(Object naturalIdValue); }
所以,假设我们有一个定义了natural id的实体
@Entity @Table(name="T_USER") public class User { @Id private Long id; @NaturalId private String username; ... }
我们可以通过以下方式按natural id加载该类的实例
session.byNaturalId( User.class ).using( "username", "steve" ).load();
这实际上确保我们得到一个初始化的实例,就像Session.get做的那样。如果我们只想得到一个可能未初始化的引用,我们可以使用这个代替
session.byNaturalId( User.class ).using( "username", "steve" ).getReference();
由于这里的natural id很简单(只是一个属性)我们可以使它更容易
session.bySimpleNaturalId( User.class ).load( "steve" );