最近我维护了一个遗留项目,它使用了hibernate 3.3.2 ga
。现在我正在为这个项目开发一个新的需求基础,即实现一个连接查询,例如有一个 foo 实体和一个 bar 实体,它们的关系是一对一一:
Foo:
Integer id; //primary key
String orderSeq; //unique key
//others
Bar:
String orderSeq; //primary key refer Foo's orderSeq
//others
Foo.hbm.xml:
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="orderSeq" type="java.lang.String">
<column name="order_seq" length="40" not-null="true" unique="true">
</column>
</property>
<one-to-one name="bar" class="com.foo.Bar" lazy="no-proxy">
<formula>order_seq</formula>
</one-to-one>
Bar.hbm.xml:
<id name="orderSeq" type="java.lang.String">
<column name="order_seq" length="40">
</column>
</id>
<one-to-one name="foo" class="com.foo.Foo" property-ref="orderSeq" lazy="no-proxy">
</one-to-one>
参见上面的配置,我明确设置了lazy="no-proxy"
,并从official documentation我知道:
lazy="no-proxy" specifies that the property should be fetched lazily when the instance variable is first accessed.
现在,当我执行以下单元测试时:
@Test
public void test_query_us_order(){
Query query = session.createQuery("from Foo a where a.orderSeq = '151207173519268'");
query.list();
}
我预计只会执行一条 SQL 语句(select ... from foo where foo0_.order_seq = 151207173519268
),但实际上还有两条 SQL 语句,例如:
select ...
from
bar bar0_
left outer join
foo foo1_
on bar0_.order_seq=foo1_.order_seq
left outer join
bar bar2_
on foo1_.order_seq=bar2_.order_seq
where
bar0_.order_seq=?
select ...
from
foo foo0_
left outer join
bar bar1_
on foo0_.order_seq=bar1_.order_seq
left outer join
foo bar2_
on bar1_.order_seq=bar2_.order_seq
where
foo0_.order_seq=?
为什么会这样呢?为什么 lazy="no-proxy"
配置不起作用?
最佳答案
您在问题中引用的文档中的 lazy
定义是:
lazy
(optional - defaults toproxy
): by default, single point associations are proxied.lazy="no-proxy"
specifies that the property should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation.lazy="false"
specifies that the association will always be eagerly fetched.
请注意这句话,其中指出无代理
需要字节码检测。这是因为如果没有它,Hibernate 将不知道您何时访问应用程序中的属性。通过修改应用程序生成的字节码,您基本上可以注入(inject)在访问属性时执行延迟加载的代码。
如果您不使用字节码检测,则应该简单地使用代理进行延迟加载,这意味着您应该将关联定义为:
lazy="proxy"
关于java - 一对一惰性 ="no-proxy"在 Hibernate 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34368895/