Hibernate: individual lazy loading, optional = false

I ran into a problem that individual lazy loading does not work in sleep mode. I already decided it , but still it’s not right to understand what is happening.

My code ( lazy loading doesn't work here when I pull out Person - Address is also selected):

@Entity public class Person{ @Id @SequenceGenerator(name = "person_sequence", sequenceName = "sq_person") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_sequence") @Column(name = "id") private long personID; @OneToOne(mappedBy="person", cascade=CascadeType.ALL, fetch = FetchType.LAZY) private Adress address; //.. getters, setters } @Entity public class Address { @Id @Column(name="id", unique=true, nullable=false) @GeneratedValue(generator="gen") @GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="person")) private long personID; @PrimaryKeyJoinColumn @OneToOne private FileInfo person; } 

But : if I add optional=false to the OneToOne relationship, lazy loading works fine !

 @OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY) private Adress address; 

Question / Entreaty: please explain to me how optional=false annotation helps to achieve lazy loading.

PS I read the posts post1 and post2 , and understand why a simple OneToOne cannot be lazy, but I still can not understand the magic of optional=false .

+42
hibernate jpa lazy-loading one-to-one
Aug 01 '13 at 7:24 on
source share
2 answers

If the association is optional, Hibernate has no way of knowing if an address exists for a given person without a request. Thus, he cannot fill in the proxy address field, because there can be no addres referring to the person, and he cannot fill it with zero, because there can be an address referring to the person.

When you make a binding association (i.e. optional=false ), it trusts you and assumes that the address exists because the association is binding. Therefore, it directly fills in the proxy address field, knowing that there is an address that refers to a person.

+61
Aug 01 '13 at 7:29 on
source share

The simplest is fake one-to-many relationships. This will work because lazy loading a collection is much easier than lazy loading a single property with the nullable option, but overall this solution is very inconvenient if you use complex JPQL / HQL queries.

Another is to use build time bytecode toolkit. For more information, please see the Hibernate document: 19.1.7. Using lazy selection of properties. Remember that in this case you need to add the @LazyToOne(LazyToOneOption.NO_PROXY) annotation to the one-to-one relationship to make it lazy. Configuring fetch for LAZY is not enough.

The final solution is to use the runtime bytecode toolkit, but it will only work for those who use Hibernate as a JPA provider in a full-blown JEE environment (in this case setting β€œ hibernate.ejb.use_class_enhancer ” to true should do the trick: Entity Manager Configuration) or use Hibernate with Spring configured to run at run time (this can be difficult to achieve on some older application servers). In this case, the @LazyToOne(LazyToOneOption.NO_PROXY) annotation @LazyToOne(LazyToOneOption.NO_PROXY) is also required.

+5
Apr 11 '16 at 5:22
source share



All Articles