hibernate bidirectional onetoone fetchtype lazy problemCategory: Hibernate2013-06-26 14:54 932 people read comments (2) favorite reports
Reproduced in: http://mshijie.javaeye.com/admin/blogs/440057
When you use JPA (Hibernate) today to implement a one-to-one association, you find that lazy loading cannot be used. The person is associated with a picture. When the person is read, the picture is displayed for the picture. Read 10 Person A database query occurred 11 times.
Finally, after reviewing the information, it was found that the understanding of Onetoone was not thorough enough. The previous association was defined as such.
Person code
- @Entity
- public class Person {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne (cascade = cascadetype.all, fetch = fetchtype.lazy, Mappedby = "person
- ")
- private picture picture;
- }
Java code
- @Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne
- private person person;
- }
[Java]View Plaincopy
- <span style="Font-size:medium;" >@Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne
- private person person;
- }
- </span>
[Java]View Plaincopy
- <span style="FONT-SIZE:14PX;" >@Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne
- private person person;
- }
- </span>
The primary table is the picture, which is the person from the table. The Foreign key field is defined in the????
Because if lazy loading is to work, you must set up a proxy object. But Personn can not associate a picture, if there is a picture association is set to proxy object lazy loading, if the picture is not present, set NULL, Since the foreign key field is defined in the picture table, hibernate cannot determine whether the object is associated with a chart without reading it, so it is not possible to set NULL or proxy objects, unify the proxy object, and not be able to satisfy the non-associative situation. So the lazy load cannot be used, only the display reads the picture.
The reason has been found. Made the following changes
Person code
- @Entity
- public class Person {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne (cascade = cascadetype.all, fetch = Fetchtype.lazy)
- private picture picture;
- }
Java code
- @Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne (mappedby = "picture")
- private person person;
- }
[Java]View Plaincopy
- <span style="Font-size:medium;" >@Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne (mappedby = "picture")
- private person person;
- }
- </span>
[Java]View Plaincopy
- <span style="FONT-SIZE:14PX;" >@Entity
- Public class Picture {
- @Id
- @GeneratedValue (strategy = generationtype.identity)
- private int id;
- @OneToOne (mappedby = "picture")
- private person person;
- }
- </span>
The master-slave relationship of the table is modified, and the foreign key field is defined in the Personnel table. Hibernate can set null or proxy objects based on foreign key fields without reading the picture table, and lazy loading will work.
In the same way, we usually use a one-to-many case is that the multi-terminal is the primary table, so you can set the proxy object or null through the foreign key field. At one end, though, hibernate cannot determine whether an object is associated. But even if the object is not associated, it should not be set to null. Instead of being set to an empty list or map, hibernate can delay loading by acting on the list or map. This is also why, when we set one end associated, the general explicit new is a ArrayList or haskmap, such as:
Java code
- @OneToMany (cascade = cascadetype.all, fetch = fetchtype.lazy, Mappedby ="Personnel")
- Private List<reward> Rewards = new arraylist<reward> ();
[Java]View Plaincopy
- <span style="Font-size:medium;" >@OneToMany (cascade = cascadetype.all, fetch = fetchtype.lazy, Mappedby = "Personnel")
- Private List<reward> Rewards = new arraylist<reward> ();</span>
[Java]View Plaincopy
- <span style="FONT-SIZE:14PX;" >@OneToMany (cascade = cascadetype.all, fetch = fetchtype.lazy, Mappedby = "Personnel")
- Private List<reward> Rewards = new arraylist<reward> ();</span>
This is to avoid using NULL to denote no association, and to use an empty list to be consistent.
Hibernate bidirectional onetoone Fetchtype lazy problem