Hibernate延迟加载不能处理多对一XML

时间:2016-05-02 04:57:39

标签: java hibernate lazy-loading

我试图在Hibernate中懒洋洋地加载一个集合。从我所读到的,这是实现这一目标的最佳实践方式:

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

但是,当我运行此单元测试时,断言失败:

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();

毋庸置疑,我有点困惑,因为其他StackOverflow线程说这是正确执行此操作的方法。我觉得我必须错过一些非常明显的东西,但我还是Hibernate的新手,并且不知道是什么。

这是此类的映射文件:

<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>

提前致谢。

更新:仍有问题,我已将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;
}

现在测试看起来像这样

@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();
}

1 个答案:

答案 0 :(得分:0)

问题是,您无法使用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());

你需要使用getter而不是属性,因为Hibernate需要有一个代理。 getter返回代理

Hibernate.initialize(this.getTruckReviews());