pierwsze, dwie zasady:
- Prokurenci delegat wszystko zakaz ostateczna metoda zwraca się do instancji docelowej, z wyjątkiem sposobu uzyskania identyfikatora jeśli dostęp nieruchomość za id jest zdefiniowany w odwzorowań.
- Instancje obiektu proxy są nigdy zainicjowane, instancja docelowa jest zainicjowana.
1) Załóżmy, że powołują a.equals(b)
gdzie zarówno a
i b
są prokurenci tego samego podmiotu. I powiedzmy, że equals
metoda jest realizowany tak:
public boolean equals(Object other) {
...
if (this.someField.equals(other.someField)) {
...
}
...
}
equals
metoda a
jest delegowana do instancji docelowej zmuszając pełnej inicjalizacji. Więc jesteś bezpieczny w odniesieniu do pól w instancji a
(możesz ich użyć bezpośrednio).
jednak dostęp do pól bezpośrednio w instancji b
(other.someField
) jest nigdy ważny. Nie ma znaczenia, czy b
jest zainicjowany, czy nie, instancja proxy nigdy nie jest inicjowana, a jedynie instancja docelowa. Tak więc someField
jest zawsze null
w instancji b
.
Prawidłowa realizacja jest użycie pobierające przynajmniej dla other
przykład:
this.someField.equals(other.getSomeField())
lub być zgodne:
this.getSomeField().equals(other.getSomeField())
są różne rzeczy, jeśli chodzi o final
metod - Hibernate nie może nadpisuj je, aby przekazać połączenie do celu. Tak więc, jeśli w poprzednim przykładzie metoda equals
byłaby final
, otrzymasz NullPointerException
podczas uzyskiwania dostępu do this.someField
.
Wszystko to można uniknąć, konfigurując Hibernate, aby używał oprzyrządowania bajtowego zamiast serwerów proxy, ale ma on własne pułapki i nie jest powszechnie stosowany.
2) Ponownie, nigdy nie inicjuje samej instancji serwera proxy. W przypadku inicjowania instancji docelowej zależy to od tego, czy w odwzorowaniach jest zdefiniowany dostęp do pola lub właściwości. W obu przypadkach używane jest odbicie (przypisanie wartości bezpośrednio do pól w przypadku dostępu do pola lub do wywołania seterów w przypadku dostępu do właściwości).