@LazyToOne(LazyToOneOption.NO_PROXY)
返回请求引用时加载的真实对象(此选项必须增强字节码,如果未增强该类,则退回到PROXY)
可以看出,在使用字节码之前需要对其进行检测。检测“字节码”后,“持久类得到增强”。
这个想法是要愚弄Hibernate,我们要使用的实体类已经被检测了
编译代码后将调用检测任务。工具实体扩展FieldHandled
。FieldHandled
是“引入增强类的接口”
Hibernate在运行时验证实体,并得出结论,类得到了增强,这就是为什么它使用真实对象而不是代理并且不像往常那样加载相关实体对象的原因。
编辑:
让我们来看看幕后花絮:
AnnotationBinder句柄 NO_PROXY
选项
if ( lazy != null ) {
toOne.setLazy( !( lazy.value() == LazyToOneOption.FALSE ) );
toOne.setUnwrapProxy( ( lazy.value() == LazyToOneOption.NO_PROXY ) );
}
这两个org.hibernate.mapping.ManyToOne
和org.hibernate.mapping.OneToOne
是的子类org.hibernate.mapping.ToOne
。ToOne#isUnwrapProxy()
唯一的用途是#getType
:
getMappings()。getTypeResolver()。getTypeFactory()。oneToOne(
这两个ManyToOneType
和OneToOneType
是的子类EntityType
,只有“的EntityType#unwrapProxy”的用法是在EntityType#resolveIdentifier(Serializable, SessionImplementor)
boolean isProxyUnwrapEnabled = unwrapProxy &&
session.getFactory()
.getEntityPersister( getAssociatedEntityName() )
.isInstrumented();
这是暂定的呼叫层次结构:AbstractEntityPersister#isInstrumented()
-> EntityMetamodel#isInstrumented()
-> EntityInstrumentationMetadata#isInstrumented()
->等,最后BytecodeProviderImpl.EntityInstrumentationMetadataImpl.EntityInstrumentationMetadataImpl()
this.isInstrumented = FieldHandled.class.isAssignableFrom( entityClass );
这就是为什么需要检测代码(例如使用InstrumentTask
)或实现的原因FieldHandled
。
为了使长话短说你可以看一看EntityType#resolveIdentifier(Serializable, SessionImplementor)
。这就是为什么即使第二个对象为空也不会加载的原因。