Ruhezustand: 1: 1-Lazy Loading, optional = false

Ich hatte das Problem, dass das Eins-zu-eins-Laden im Ruhezustand nicht funktioniert. Ich habe es schon getriggers , verstehe aber immer noch nicht richtig was passiert.

Mein Code ( Lazy Loading funktioniert hier nicht , wenn ich Person – Address zieht):

@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; } 

Aber : wenn ich in der OneToOne-Beziehung optional=false hinzufüge, funktioniert das faule Laden gut !

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

Question / Entreaty: Bitte erklären Sie mir, wie optional=false Annotation hilft, lazy loading zu erreichen.

PS Ich habe Posts post1 und post2 gelesen und verstehe, warum einfaches OneToOne nicht faul sein kann, aber ich kann immer noch nicht optional=false Magie begreifen.

    Wenn die Zuordnung optional ist, kann Hibernate nicht feststellen, ob eine Adresse für eine bestimmte Person vorhanden ist, ohne eine Abfrage auszugeben. Daher kann das Adressfeld nicht mit einem Proxy gefüllt werden, da es keine Adressen geben kann, die auf die Person verweisen, und sie kann keine Null enthalten, da möglicherweise eine Adresse auf die Person verweist.

    Wenn Sie die Assoziation obligatorisch machen (dh optional=false ), vertraut sie Ihnen und nimmt an, dass eine Adresse existiert, da die Assoziation obligatorisch ist. Daher füllt es das Adressfeld direkt mit einem Proxy, da es eine Adresse gibt, die auf die Person verweist.

    Am einfachsten ist es, eine Eins-zu-Viele-Beziehung zu fälschen. Dies wird funktionieren, da das verzögerte Laden der Sammlung viel einfacher ist als das verzögerte Laden einzelner Nullable-Eigenschaften, aber im Allgemeinen ist diese Lösung sehr unpraktisch, wenn Sie komplexe JPQL / HQL-Abfragen verwenden.

    Die andere Methode ist die Verwendung der Bytecode-Instrumentierung für die Build-Zeit. Weitere Informationen finden Sie in der Hibernate-Dokumentation: 19.1.7. Verwenden von faulen Eigenschaften abrufen. Denken Sie daran, dass Sie in diesem Fall die @LazyToOne(LazyToOneOption.NO_PROXY) zu einer 1: 1-Beziehung hinzufügen @LazyToOne(LazyToOneOption.NO_PROXY) , um sie faul zu machen. Das Abrufen von LAZY reicht nicht aus.

    Die letzte Lösung ist die Laufzeit-Bytecode-Instrumentierung, aber sie funktioniert nur für diejenigen, die Hibernate als JPA-Provider in einer vollständigen JEE-Umgebung verwenden (in diesem Fall sollte die Einstellung ” hibernate.ejb.use_class_enhancer ” auf true gesetzt werden): Entity Manager Configuration ) oder verwenden Sie Hibernate mit Spring, das für das Runtime Weben konfiguriert ist (dies kann auf einigen älteren Anwendungsservern nur schwer erreicht werden). In diesem Fall wird auch die Annotation @LazyToOne(LazyToOneOption.NO_PROXY) benötigt.