gpt4 book ai didi

java - 使用 hbm 实现 Hibernate 一对多延迟加载

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:06:01 26 4
gpt4 key购买 nike

我有几个类,StudentAddress。要获得一对多关系,假设一个学生可以有多个地址。我为此结构创建了 .hbm 文件,但我想懒惰地为学生加载地址。但它总是在学生对象中加载地址。我可以看到一些查询被解雇了。比如从 Student 表和 Address 表中获取信息。

lazy=truelazy=false 没有任何效果,始终触发 2 个查询(学生和地址)。

学生.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>

地址.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 ));

最佳答案

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

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

引用自 Java Persistence with Hibernate

A proxy is initialized if you call any method that is not the identifier getter method, a collection is initialized if you start iterating through its elements or if you call any of the collection-management operations, such as size() and contains()

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

关于java - 使用 hbm 实现 Hibernate 一对多延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21413959/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com