用hbm来休眠一对多的延迟加载

时间:2014-01-28 18:34:05

标签: java hibernate lazy-loading

我有几个课程StudentAddress。为了获得一对多关系,假设一个学生可以拥有多个地址。我为这个结构创建了.hbm文件,但我想懒惰地为学生加载地址。但它始终在学生对象中加载地址。我可以看到一些问题被解雇了。就像从学生表和地址表中获取信息一样。

lazy=truelazy=false没有任何效果,并且总是会触发2个查询(学生和地址)。

Student.hbm:

 <?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="hibernate.s4.Student" table="STUDENT">

<id name="studentId" column="stdid">
    <generator class="increment" />
</id>

<property name="studentName" column="stdname" length="10"/>
<property name="phoneno" column="phno" length="10"/>
<property name="degree" column="degree" length="10"/>

<set name="addresses" cascade="save-update" lazy="false">
    <key column="studentId"></key>
    <one-to-many class="hibernate.s4.Address"/>
</set>

</class>
</hibernate-mapping>

Address.hbm:

<?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="hibernate.s4.Address" table="ADDRESS">

<id name="addressid" column="addrid">
    <generator class="increment" />
</id>

<property name="location" column="location" length="10"/>
<property name="area" column="area" length="10"/>
<property name="pin" column="pin" length="6"/>

</class>
</hibernate-mapping>

用于保存数据和获取学生对象的客户端类:

Transaction tx = session.beginTransaction();

Student std1 = new Student();
std1.setStudentName("balaji");
std1.setDegree("MCA");
std1.setPhoneno("XXX777CXCC");
session.save(std1);

Address adr1 = new Address();
adr1.setArea("chirala");
adr1.setLocation("AP");
adr1.setPin(523155);
adr1.setStudent(std1);
Address adr3 = new Address();
adr3.setArea("pune");
adr3.setLocation("MH");
adr3.setPin(411028);
adr3.setStudent(std1);
std1.getAddresses().add(adr1);
std1.getAddresses().add(adr3);


System.out.println("Object saved successfully.....!!");
tx.commit();

Query query = session.createQuery("from Student where studentId = :studentId");
query.setParameter("studentId", 1);
List list = query.list();
Student student = (Student)list.get(0);
System.out.println((student.getAddresses() != null ? student.getAddresses().size() : 0 ));

1 个答案:

答案 0 :(得分:1)

最后在println上与您的代码有几个问题:System.out.println((student.getAddresses() != null ? student.getAddresses().size() : 0 ));

student.getAddresses()永远不会为null,因为Hibernate对非读取集合使用代理对象。同时在您的子集合上调用.size()将使hibernate在该点初始化集合。所以它开头并不是空的,并且通过调用.size()你强迫集合被初始化。

引用来自Java Persistence with Hibernate

  

如果您调用任何不是标识符getter方法的方法,则初始化代理,如果您开始迭代其元素或者调用任何集合管理操作(如size()和contains),则初始化集合()

您可以尝试将地址设置为lazy="extra",这样当您致电.size()时,它只会获取集合大小(即select count(*) from addresses),而不是整个集合本身。