简体   繁体   English

休眠延迟加载不适用于多对一映射

[英]Hibernate lazy loading not work with many-to-one mapping

I have problem of performance in my many-to-one mapping. 我的多对一映射存在性能问题。 When I debug the SQL query in log file the principal query it's ok, but after i have other query representing many-to-one object mapping. 当我在日志文件中调试SQL查询时,可以进行主体查询,但是在我有其他表示多对一对象映射的查询之后。

Entity.hbm.xml : Entity.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
    <class name="com.omb.database.mapping.MyEntity" table="MY_ENTITY">
        <id name="id" type="java.lang.Integer">
            <column name="ENTITY_ID"/>
            <generator class="sequence">
                <param name="sequence">SEQ_MY_ENTITY</param>
            </generator>
        </id>

        <property name="prop1" type="string" column="PROP1" />
        <many-to-one name="object1" column="OBJECT1_ID" class="com.omb.database.mapping.Object1" />
        <many-to-one name="object2" column="OBJECT2_ID" class="com.omb.database.mapping.Object2" /> 

    </class>
</hibernate-mapping>

Object1.hbm.xml : Object1.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping default-lazy="true">

    <class name="com.omb.database.mapping.Object1" table="TABLE_OBJECT_1">
        <id name="id" type="java.lang.Integer" column="OBJECT1_ID" />
        <property name="label" type="string" column="LABEL_OBJECT_1" length="15" />
    </class>

</hibernate-mapping>

Object2.hbm.xml : Object2.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping default-lazy="true">

    <class name="com.omb.database.mapping.Object2" table="TABLE_OBJECT_2">
        <id name="id" type="java.lang.Integer" column="OBJECT2_ID" />
        <property name="label" type="string" column="LABEL_OBJECT_2" length="15" />
    </class>

</hibernate-mapping>

Query HBM : 查询HBM:

public List<Entity> findByObject1Id(Integer object1Id) throws DataAccesException {

        List<Entity> results = null;
        try {
            Query query = this.getSession().createQuery(
                    "from Entity ent where ent.object1.id = :object1Id");
            query.setParameter("object1Id", object1Id);
            results = query.list();
        } catch (HibernateException hbe) {
            throw new DataAccesException(hbe);
        }

        return results;
    }

in pom.xml 在pom.xml中

<!-- Hibernate 3 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate</artifactId>
            <version>3.2.6.ga</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>net.sf.ehcache</groupId>
                    <artifactId>ehcache</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm-attrs</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

Your mapping seems to be ok. 您的映射似乎没问题。 As documented here 5.1.1. 如此处所述5.1.1。 Entity 实体

The <class> attribute lazy is by default true <class>属性lazy默认为true

  • lazy (optional): lazy fetching can be disabled by setting lazy="false". 懒惰(可选):可以通过设置lazy =“ false”来禁用懒惰获取。

The same for <many-to-one> : 5.1.7.1. <many-to-one>5.1.7.1。 Using a foreign key or an association table lazy attribute: 使用外键或关联表的 惰性属性:

  • 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. lazy="no-proxy"指定第一次访问实例变量时应延迟获取属性。 This requires build-time bytecode instrumentation. 这需要构建时字节码检测。 lazy="false" specifies that the association will always be eagerly fetched. lazy="false"指定将始终渴望获取关联。

So, where is the issue? 那么,问题出在哪里呢?

I would say in your debug window . 我会在您的调试窗口中说。 Because you do have a reference to your list, and you are watching the result - in the moment it is executed - the reference is also loaded. 因为您确实有对列表的引用,并且您正在监视结果-在执行结果的同时-该引用也已加载。 Lazily - but loaded. 懒惰的-但加载。 That's in fact what we want. 实际上,这就是我们想要的。 Proxy - when firstly tuched - is forcing the load. 代理-首次学习时-正在强制加载。

Try to remove it from watch. 尝试将其从手表中删除。 Or close the session and then put it in the watch... You should see, taht the query used above - is not loading references... only when really accessed... even via debug window 或者关闭会话,然后将其放到手表中……您应该看到,在上面使用的查询中-仅在真正访问时才加载引用...甚至通过调试窗口也是如此

您是否尝试过像这样的FetchMode.SELECT?

<many-to-one name="object1" column="OBJECT1_ID" class="com.omb.database.mapping.Object1" fetch="select" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM