我试图在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();
}
答案 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());