我有几个课程Student
和Address
。为了获得一对多关系,假设一个学生可以拥有多个地址。我为这个结构创建了.hbm文件,但我想懒惰地为学生加载地址。但它始终在学生对象中加载地址。我可以看到一些问题被解雇了。就像从学生表和地址表中获取信息一样。
lazy=true
或lazy=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 ));
答案 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
),而不是整个集合本身。