简体   繁体   English

Hibernate延迟加载无法使用多对一XML

[英]Hibernate lazy loading not working many-to-one XML

I'm trying to lazily load a collection in Hibernate. 我试图在Hibernate中延迟加载一个集合。 From what I've read this is the best practice way to do this: 根据我的阅读,这是执行此操作的最佳实践方法:

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Hibernate.initialize(this.truckReviews);
session.getTransaction().commit();
session.close();
return this.truckReview;

However, when I run this unit test, the assertion fails: 但是,当我运行此单元测试时,断言失败:

Truck realTruck = Truck.getTruckByID(1);
TruckReview realFakeReview = new TruckReview();
realFakeReview.setTruck(realTruck);
realFakeReview.setUser(IntegrationTestResources.getTestUser());
realFakeReview.setReviewDate(new Date());
realFakeReview.setReviewStars(5);
realFakeReview.setReviewText("fake review");
realFakeReview.save();
assertTrue(realTruck.loadReviews().contains(realFakeReview));
realFakeReview.delete();

Needless to say, I'm a bit confused since other StackOverflow threads say this is the way to do it properly. 不用说,我有点困惑,因为其他StackOverflow线程都说这是正确执行此操作的方法。 I feel like I must be missing something very obvious but I'm still new to Hibernate and have no idea what. 我觉得我肯定想念一些很明显的东西,但是我对Hibernate还是陌生的,也不知道该怎么办。

Here's the mapping file for this class: 这是此类的映射文件:

<hibernate-mapping>
<class name="edu.temple.tutrucks.Truck" table="truck" catalog="TUTrucks" optimistic-lock="version">
    <id name="id" type="int">
        <column name="id" />
        <generator class="identity" />
    </id>
    <property name="truckName" type="string">
        <column name="truck_name" not-null="true" />
    </property>
    <property name="latitude" type="double">
        <column name="latitude" precision="22" scale="0" not-null="true" />
    </property>
    <property name="longitude" type="double">
        <column name="longitude" precision="22" scale="0" not-null="true" />
    </property>
    <property name="openingTime" type="imm_time">
        <column name="opening_time" not-null="false"></column>
    </property>
    <property name="closingTime" type="imm_time">
        <column name="closing_time" not-null="false"></column>
    </property>
    <property name="avatar" type="string">
        <column name="avatar"></column>
    </property>
    <list name="truckReviews" table="truck_review" inverse="true" lazy="true" fetch="select">
        <key>
            <column name="truck_id" />
        </key>
        <list-index column="review_stars" />
        <one-to-many class="edu.temple.tutrucks.TruckReview" />
    </list>
    <list name="menus" table="menu" inverse="true" lazy="false" fetch="select">
        <key>
            <column name="truck_id" />
        </key>
        <list-index column="id" />
        <one-to-many class="edu.temple.tutrucks.Menu" />
    </list>
    <set name="tags" table="tag_truck_map" inverse="true" lazy="true" fetch="select">
        <key>
            <column name="truck_id" />
        </key>
        <many-to-many column="tag_id" class="edu.temple.tutrucks.Tag"></many-to-many>
    </set>
</class>
</hibernate-mapping>

Thanks in advance. 提前致谢。

UPDATE: Still having issues, I've changed the loadReviews method to this 更新:仍然有问题,我将loadReviews方法更改为此

@Override
public Truck loadReviews() { // lazy loading needs to be fixed
    Session session = HibernateUtil.getSessionFactory().openSession();
    session.beginTransaction();
    Truck retval = (Truck) session.get(Truck.class, this.getId());
    Hibernate.initialize(retail.getTruckReviews());
    session.getTransaction().commit();
    session.close();
    retval.truckReviews.size();
    return retval;
}

And the test now looks like this 现在测试看起来像这样

@Test
public void testloadReviews() {
    Truck realTruck = Truck.getTruckByID(1, false, false);
    TruckReview realFakeReview = new TruckReview();
    realFakeReview.setTruck(realTruck);
    realFakeReview.setUser(IntegrationTestResources.getTestUser());
    realFakeReview.setReviewDate(new Date());
    realFakeReview.setReviewStars(5);
    realFakeReview.setReviewText("fake review");
    realFakeReview.save();
    assertTrue(realTruck.loadReviews().getTruckReviews().contains(realFakeReview));
    realFakeReview.delete();
}

The problem is that you can't to use realTruck form one session to do Hibernate.initialize(this.truckReviews) using other session 问题是您不能在一个会话中使用realTruck形式使用其他会话进行Hibernate.initialize(this.truckReviews)

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
// you need to reload persistent with 
// realTruck = session.get(), realTruck = session.load() here
Hibernate.initialize(this.getTruckReviews());

You need to use a getter not a property, because of Hibernate need to have a proxy. 您需要使用getter而不是属性,因为Hibernate需要具有代理。 A proxy is returned by a getter 代理由getter返回

Hibernate.initialize(this.getTruckReviews());

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

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