Frage

Ich habe ein Problem mit dem faulen Laden im Winterschlaf im Umgang mit Erbschaft. Ich habe eine Entität, die auf eine zweite Entität verweist, die unterklassifiziert ist. Ich möchte den Hinweis auf faul ladet, aber dies verursacht Fehler in meinen .equals () -Methoden.

Wenn Sie im folgenden Code in einer Instanz von A Equals () aufrufen Proxy, das von Javassist erstellt wurde, das B erweitert, nicht C.

Ich verstehe, dass Hibernate keinen Proxy von Typ C erstellen kann, ohne in die Datenbank zu gehen und damit das faule Laden zu brechen. Gibt es eine Möglichkeit, die Getb () -Funktion in der Klasse A zurückzusetzen, die Beton -B -Instanz anstelle des Proxy (träge)? Ich habe versucht, die Annotation von Hibernate -spezifisch @lazytoone (lazytooneOption.no_proxy) auf der GetB () -Methode ohne Erfolg zu verwenden.

@Entity @Table(name="a")
public class A {
    private B b;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="b")
    public B getB() {
        return this.b;
    }

    public boolean equals(final Object o) {
        if (o == null) {
            return false;
        }

        if (!(o instanceof A)) {
            return false;
        }
        final A other = (A) o;
        return this.getB().equals(o.getB());
    }
}

@Entity @Table(name="b")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="type",
    discriminatorType=DiscriminatorType.STRING
)
public abstract class B {
   private long id;

   public boolean equals(final Object obj) {
       if (this == obj) {
           return true;
       }
       if (obj == null) {
           return false;
       }
       if (!(obj instanceof B)) {
           return false;
       }
       final B b = (B) o;
       return this.getId().equals(b.getId());
    }
}

@Entity @DiscriminatorValue("c")
public class C extends B {
   private String s;

   public boolean equals(Object obj) {
       if (this == obj) {
           return true;
       }
       if (!super.equals(obj)) {
           return false;
       }
       if (obj == null) {
           return false;
       }
       if (!super.equals(obj)) {
           return false;
       }
       if (!(obj instanceof C)) {
           return false;
       }
       final C other = (C) o;
       if (this.getS() == null) {
           if (other.getS() != null) {
               return false;
           }
       } else if (!this.getS().equals(other.getS())) {
           return false;
       }
       return true;
    }
}

@Entity @DiscriminatorValue("d")
public class D extends B {
    // Other implementation of B
}
War es hilfreich?

Lösung

Es stellt sich heraus, dass ich auf der rechten Verfolgung war und versucht habe, die Annotation von @lazytoone (LazytooneOption.no_proxy) zu verwenden. Es funktioniert nicht für mich aus der Box, weil ich das Hibernate -Bytecode Enhancer -Tool noch nicht ausgeführt hatte. Anweisungen hierfür finden Sie hier:

19.1.7. Verwenden von faulen Eigenschaften abrufen

Andere Tipps

Vielleicht möchten Sie versuchen, das zu ändern fetch Eigenschaft auf getb () zu FetchType.EAGER. Hoffe das hilft.

Unabhängig davon, ob die Objekte Entitäten und/oder faul geladen sind, ist es praktisch unmöglich, den Vertrag von Gleichen zu respektieren und eine Spezialisierung von Gleichen in einer Unterklasse zu haben, die Instanz verwendet. In der Tat wären Sie dann in einer Situation, in der Sie hätten b1.equals(c1) == true, aber c1.equals(b1) == false.

Ich denke also, die Superklasse (b) sollte gleich definieren und es endgültig machen, da alle Unterklassen die Basisklasse verwenden sollten equals Methode.

Trotzdem ist Ihre Equals -Methode in B nicht richtig:

if (!super.equals(obj)) {
   return false;
}

Dies bedeutet, dass die Objektimplementierung von Equals true zurückgeben muss, um zwei B -Instanzen gleich zu haben. Dies bedeutet, dass zwei B -Instanzen nur dann gleich sind, wenn sie dasselbe Objekt sind.

if (!(obj instanceof C)) {
    return false;
}

Warum prüft die B -Klasse, dass die andere Instanz eine Instanz von C ist. Es sollte überprüfen, ob die andere Instanz eine Instanz von B. ist

Da am Ende zwei Bs gleich sind, wenn sie dieselbe ID haben, und die IDs für den gesamten Vererbungsbaum eindeutig sein müssen, sind Sie sicher, wenn Sie diese gleiche Methode endgültig machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top