Frage

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Problem {
    @ManyToOne
    private Person person;
}

@Entity
@DiscriminatorValue("UP")
public class UglyProblem extends Problem {}

@Entity
public class Person {
    @OneToMany(mappedBy="person")
    private List< UglyProblem > problems;
}

Ich denke, es ist ziemlich klar, was ich zu tun versuche.Ich erwarte, dass die Person @ManyToOne von der UglyProblem-Klasse geerbt wird.Es wird jedoch eine Ausnahme geben, die etwa Folgendes sagt:„In der UglyProblem-Klasse (mappedBy="person") wurde keine solche Eigenschaft gefunden.“

Alles was ich gefunden habe ist Das.Ich konnte den Beitrag von Emmanuel Bernard, in dem die Gründe dafür erläutert werden, nicht finden.


Leider heißt es in der Hibernate-Dokumentation: „Eigenschaften von Superklassen, die nicht als @MappedSuperclass zugeordnet sind, werden ignoriert.“

Nun, ich denke, das bedeutet, dass ich, wenn ich diese beiden Klassen habe:

public class A {
    private int foo;
}

@Entity
public class B extens A {
}

dann Feld foo wird nicht für Klasse B abgebildet.Was Sinn macht.Aber wenn ich so etwas habe:

@Entity
public class Problem {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

@Entity
public class UglyProblem extends Problem {

private int levelOfUgliness;

public int getLevelOfUgliness() {
    return levelOfUgliness;
}

public void setLevelOfUgliness(int levelOfUgliness) {
    this.levelOfUgliness = levelOfUgliness;
}
}

Ich erwarte, dass die Klasse UglyProblem Dateien hat id Und name und beide Klassen sollen über dieselbe Tabelle zugeordnet werden.(Tatsächlich passiert genau das, ich habe gerade noch einmal nachgeschaut).Ich habe diese Tabelle:

CREATE TABLE "problem" (
    "DTYPE" varchar(31) NOT NULL,
    "id" bigint(20) NOT NULL auto_increment,
    "name" varchar(255) default NULL,
    "levelOfUgliness" int(11) default NULL,
    PRIMARY KEY  ("id")
) AUTO_INCREMENT=2;

Zurück zu meiner Frage:

Ich erwarte, dass die Person @ManyToOne von der UglyProblem-Klasse geerbt wird.

Ich gehe davon aus, dass alle anderen zugeordneten Felder vererbt werden und ich keinen Grund sehe, diese Ausnahme für ManyToOne-Beziehungen zu machen.


Ja, das habe ich gesehen.Tatsächlich habe ich für meinen Fall eine schreibgeschützte Lösung verwendet.Aber meine Frage war „Warum...“ :).Ich weiß, dass es eine Erklärung von einem Mitglied des Hibernate-Teams gibt.Ich konnte es nicht finden und habe deshalb nachgefragt.

Ich möchte die Motivation dieser Designentscheidung herausfinden.

(Wenn Sie interessiert sind, wie ich mit diesem Problem umgegangen bin:Ich habe ein Projekt geerbt, das mit Hibernate 3 erstellt wurde.Es war Jboss 4.0. Etwas + Ruhezustand war bereits vorhanden (Sie würden alles zusammen herunterladen).Ich habe dieses Projekt auf Jboss 4.2.2 verschoben und herausgefunden, dass es geerbte Zuordnungen von „@OneToMany mappedBy“ gibt, und es funktionierte im alten Setup einwandfrei ...)

War es hilfreich?

Lösung

Ich denke, es ist eine kluge Entscheidung des Hibernate-Teams.Sie könnten weniger arrogant sein und deutlich machen, warum es auf diese Weise umgesetzt wurde, aber genau so funktionieren Emmanuel, Chris und Gavin.:) :)

Versuchen wir, das Problem zu verstehen.Ich denke, Ihre Konzepte sind „lügen“.Zuerst sagen Sie, dass es viele sind Problems sind damit verbunden Menschen.Aber dann sagst du das Person viele ... haben Hässliches Problems (und bezieht sich nicht auf andere ProblemS).Mit diesem Design stimmt etwas nicht.

Stellen Sie sich vor, wie es der Datenbank zugeordnet wird.Sie haben eine einzelne Tabellenvererbung, also:

          _____________
          |__PROBLEMS__|          |__PEOPLE__|
          |id <PK>     |          |          |
          |person <FK> | -------->|          |
          |problemType |          |_________ |
          -------------- 

Wie wird der Ruhezustand die Erstellung der Datenbank erzwingen? Problem beziehen sich nur auf Menschen wenn es Problemtyp ist gleich UP?Das ist ein sehr schwer zu lösendes Problem.Wenn Sie also eine solche Beziehung wünschen, muss sich jede Unterklasse in einer eigenen Tabelle befinden.Das ist, was @MappedSuperclass tut.

PS.:Entschuldigung für die hässliche Zeichnung :D

Andere Tipps

In meinem Fall wollte ich den Vererbungstyp SINGLE_TABLE verwenden, daher war die Verwendung von @MappedSuperclass keine Option.

Was funktioniert, wenn auch nicht sehr sauber, ist das Hinzufügen des proprietären Hibernate @Wo -Klausel für die @OneToMany-Assoziation, um den Typ in Abfragen zu erzwingen:

@OneToMany(mappedBy="person")
@Where(clause="DTYPE='UP'")
private List< UglyProblem > problems;

Leider laut Hibernate Dokumentation "Eigenschaften von Oberklassen, die nicht als @MappedSuperclass zugeordnet sind, werden ignoriert." Ich bin auch damit konfrontiert worden.Meine Lösung bestand darin, die gewünschte Vererbung über Schnittstellen und nicht über die Entity-Beans selbst darzustellen.

In Ihrem Fall könnten Sie Folgendes definieren:

public interface Problem {
    public Person getPerson();
}

public interface UglyProblem extends Problem {
}

Implementieren Sie diese Schnittstellen dann mithilfe einer abstrakten Oberklasse und zwei Entitätsunterklassen:

@MappedSuperclass
public abstract class AbstractProblemImpl implements Problem {
    @ManyToOne
    private Person person;

    public Person getPerson() {
        return person;
    }
}

@Entity
public class ProblemImpl extends AbstractProblemImpl implements Problem {
}

@Entity
public class UglyProblemImpl extends AbstractProblemImpl implements UglyProblem {
}

Ein zusätzlicher Vorteil besteht darin, dass Sie die zugrunde liegenden Zuordnungen später einfacher ändern können, wenn Sie die Schnittstellen und nicht die tatsächlichen Entity-Beans, die diese Schnittstellen implementieren, zum Codieren verwenden (geringeres Risiko einer Kompatibilitätsstörung).

Ich denke, Sie müssen Ihre Kommentare kommentieren Problem Superklasse mit @MappedSuperclass anstatt @Juristische Person.

Ich habe herausgefunden, wie man das OneToMany-mappedBy-Problem löst.

In der abgeleiteten Klasse UglyProblem aus dem ursprünglichen Beitrag.Die Rückrufmethode muss sich in der abgeleiteten Klasse befinden, nicht in der übergeordneten Klasse.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@ForceDiscriminator
public class Problem {

}

@Entity
@DiscriminatorValue("UP")
public class UglyProblem extends Problem {
    @ManyToOne
    private Person person;
}

@Entity
public class Person {
    @OneToMany(mappedBy="person")
    private List< UglyProblem > problems;
}

Zumindest die geheime Soße für die Verwendung von Hibernate gefunden. http://docs.jboss.org/hibernate/stable/annotations/api/org/hibernate/annotations/ForceDiscriminator.html Der @ForceDiscriminator sorgt dafür, dass @OneToMany den Diskriminator würdigt

Erfordert Hibernate-Anmerkungen.

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