java - 一对一惰性 ="no-proxy"在 Hibernate 中不起作用

标签 java hibernate one-to-one

最近我维护了一个遗留项目,它使用了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 to proxy): 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/

相关文章:

java - 如何使用旧的 hibernate 条件进行批处理?

java - 在 O(1) 中与 getKey(B) 一对一映射数据结构 (A,B)?

java - 从 .properties 文件为 JUnit 初始化一个常量,该文件本身是从 pom.xml 文件初始化的

java - 在界面上查找注释

java - JPA 和 Hibernate 在使用 JSON 的 Spring Rest 中第一次尝试时不会更新一对多关系

java - Hibernate 是否必须驱动数据库设计?

java - 在 Hibernate 中保留一对一关系实体 - 实体已分离

java - 在Spring中建立b/n实体一对一的关系并存储外键值

java - 当我在 Apache PDFBox 2.x 中为带有 moveTo/lineTo/stroke 的版本切换已弃用的 drawLine() 方法时,为什么我的线条消失了?

java - 通过 JSTL 访问列表时出现异常