JPA一对一关联的时候无法使用延迟加载问题解决
来源:互联网 发布:京东mac客户端下载 编辑:程序博客网 时间:2024/04/30 02:52
转载于:http://mshijie.javaeye.com/admin/blogs/440057
今天使用JPA(Hibernate)实现一个一对一关联的时候,发现无法使用延迟加载.Person关联一个Picture.在读取Person的时候,显示的记载了对于的Picture.读取10个Person发生了11次数据库查询.
最后查阅资料后,发现是自己对OneToOne理解不够透彻所致.之前的关联是这么定义的.
- @Entity
- public class Person {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "Person
- ")
- private Picture picture;
- }
- @Entity
- public class Picture {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne
- private Person Person;
- }
- <span style="font-size: medium;">@Entity
- public class Picture {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne
- private Person Person;
- }
- </span>
主表是Picture,从表是Person.外键字段定义在Picture表中.在这种情况下.读取Person会现实的读取Picture.
因为如果延迟加载要起作用,就必须设置一个代理对象.但是Personn可以不关联一个Picture,如果有Picture关联就设置为代理对象延迟加载,如果不存在Picture就设置null,因为外键字段是定义在Picture表中的,Hibernate在不读取Picture表的情况是无法判断是否关联有Picture,因此无法判断设置null还是代理对象,统一设置为代理对象,也无法满足不关联的情况,所以无法使用延迟加载,只有显示读取Picture.
原因找到了.做了如下修改
- @Entity
- public class Person {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
- private Picture picture;
- }
- @Entity
- public class Picture {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne(mappedBy = "picture)
- private Person Person;
- }
- <span style="font-size: medium;">@Entity
- public class Picture {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
- @OneToOne(mappedBy = "picture)
- private Person Person;
- }
- </span>
修改了表的主从关系,这时外键字段定义在Personnel表中.Hibernate就可以在不读取Picture表的情况下根据外键字段设置null或者代理对象,延迟加载也就起作用了.
同样的道理,我们平时在使用一对多的情况是,多端是主表,因此可以通过外键字段判断进而设置代理对象或者null.而在一端,虽然 Hibernate无法判断是否关联有对象.但是即使不关联对象时也不应该设置为null,而应该设置为一个空的List或者Map,那么 Hibernate就可以通过代理这个List或者Map实现延迟加载.这也是为什么,我们在设置一端关联时,一般显式的new一个ArrayList或者HaskMap,如:
- @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "personnel")
- private List<Reward> rewards = new ArrayList<Reward>();
- <span style="font-size: medium;">@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "personnel")
- private List<Reward> rewards = new ArrayList<Reward>();</span>
这就是为了避免使用null表示没有关联,和使用空的List一致.
- JPA一对一关联的时候无法使用延迟加载问题解决
- NHibernate中一对一关联的延迟加载
- JPA 一对一双向关联
- 关于Hibernate一对一延迟加载的总结
- [译文]JPA的实施模式:双向关联与延迟加载之间的矛盾
- jpa hibernate延迟问题解决
- JPA一对一双向关联实例
- JPA关联映射 - 一对一映射
- jpa双向一对一关联关系
- JPA的双向一对多和双向一对一关联关系
- JPA学习笔记-映射双向一对一的关联关系
- JPA之JPA中的双向一对一关联
- [译文]JPA的实施模式:延迟加载
- JPA 延迟加载
- spring jpa 延迟加载
- 一对一延迟加载问题探讨
- 关于Hibernate一对一不能延迟加载的总结
- 关于Hibernate一对一不能延迟加载的总结
- KineticJS
- NB可阻塞队列
- EBS采购模块中的级联接收和级联接收事务
- css2
- Java开发中的23种设计模式详解
- JPA一对一关联的时候无法使用延迟加载问题解决
- php之preg_replace详解
- log4net使用详解
- uva 1363 - Joseph's Problem(数论)
- C++智能指针--auto_ptr指针
- 链道桌陈咽段挥战毡督谋亚丫澈啥
- ubuntu12.04 compile android 4.4 errors
- Two Rabbits - HDU 4745 变形最长非连续回文串
- CentOS下重新安装 vsftpd