2 Stimmen

hibernate @DiscriminatorValue gilt nicht für Assoziationen

Ich habe die folgende Vererbungshierarchie.

@Entity
@Table(FRUIT)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColum(name="FRUIT_TYPE",discriminatorType=STRING)
public class Fruit {
..
@Id
private FruitId id;
...
}

@DiscriminatorValue("APPLE")
public class Apple extends Fruit {
...
@ManyToOne
private FruitBowl bowl; //this association is only present in the subclass

...
}

class FruitBowl .. {
...
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "bowl")
    @IndexColumn(name="POSITION",base = 1) 
        List<Apple> apples;
...

Wenn ich eine session.load(Apple.class,...) fügt sie hinzu FRUIT_TYPE = 'APPLE' zur Select-Abfrage. Wenn ich jedoch eine select-Abfrage für FruitBowl (die eine 1:m-Beziehung zu Apple hat) mache, enthält die select-Abfrage für Apple nicht FRUIT_TYPE = 'APPLE' . Wie kommt es dazu? Wie kann ich das Problem beheben?

Abfrage -- Abfrage für FruitBowl

select fruitbowl0_.BOWL_ID as BOWL1_1_0_ from FRUITBOWL fruitbowl0_ where fruitbowl0_.BOWL_ID=? 

--Abfrage nach Obst, um Äpfel zu finden (Datensätze mit fruit_type ='A') -aber diese Bedingung ist nicht enthalten

select apples0_.ENTITY_ID as ENTITY3_1_, apples0_.POS as POS1_, apples0_.POS as POS0_0_, apples0_.ENTITY_ID as ENTITY3_0_0_, apples0_.COLOR as COLOR0_0_ from FRUIT apples0_ where apples0_.ENTITY_ID=?

0voto

ChssPly76 Punkte 97241

(Bearbeitet auf der Grundlage von Mappings / SQL-Abfragen / Beispieldaten, die in der Frage / den Kommentaren gepostet wurden).

Ihr Mapping legt fest, dass FruitBowl enthält eine Sammlung von Apple s. Hibernate fügt daher keine Diskriminatorwert-Bedingung zur Loader-Abfrage für diese Sammlung hinzu, weil es im Voraus weiß, dass nur Apple Instanzen zurückgegeben werden können.

Die SQL-Abfragen, die Sie gepostet haben, tun genau das - sie laden FruitBowl nach id und laden Sie anschließend apples Sammlung für diese FruitBowl Instanz. Das Problem liegt in den Daten, die Sie veröffentlicht haben:

 fruit\_type entity\_id  pos  color
     A         1        1   white
     B         1        2   blue

Es gibt einen weiteren Fall von Fruit mit Diskriminatorwert B - Banana ? :-) - die das gleiche hat entity_id und wird daher als Teil der Abfrage zum Laden der Sammlung abgerufen. Hier stellt sich die Frage: Wie wurde sie überhaupt eingefügt? Es gibt zwei mögliche Szenarien:

  1. Banana ist eine Unterklasse von Apple . In diesem Fall ist alles richtig, es sollte als Teil von apples Sammlung.
  2. Sie haben die oben genannten Daten zu Testzwecken manuell eingegeben. Diese Daten sind vom Standpunkt von Hibernate aus gesehen unzulässig - sie hätten NIEMALS von Hibernate selbst eingefügt werden; dies wiederum führt zu dem Verhalten, das Sie beobachten. Sie müssen entweder die Banana Zeile oder entfernen Sie deren entity_id (und damit aus der apples Sammlung).

Im Allgemeinen ist es keine gute Idee, Objekthierarchie und Sammlungselemente in derselben Tabelle zu mischen. Ziehen Sie in Erwägung, entweder die Hierarchie als "Tabelle pro Unterklasse" neu abzubilden oder die Tabelle apples Sammlung mit @JoinTable - beachten Sie, dass sie im letzteren Fall unidirektional wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X