2 Stimmen

Hibernate "JOIN ... ON"?

Ich habe eine Anwendung, die Hibernate für ihre Domänenobjekte verwendet. Ein Teil der App ist bei einigen Apps gemeinsam und hat keine Kenntnisse über die anderen Systeme. Um Beziehungen zu handhaben, sieht unsere Klasse so aus:

@Entity
public class SystemEvent {
   @Id @GeneratedValue
   public int entity_id;

   @Column(name="event_type")
   public String eventType;

   @Column(name="related_id")
   public int relatedObjectId;
}

relatedObjectId enthält einen Fremdschlüssel zu einem von mehreren verschiedenen Objekten, abhängig vom Typ des Ereignisses. Wenn ein System über Ereignisse informiert werden möchte, die für seine Interessen relevant sind, holt es sich alle Systemereignisse mit dem Ereignistyp "Neue Konten" oder etwas Ähnlichem und weiß, dass all diese relatedObjectIds IDs zu einem "Benutzer" oder Ähnlichem sind.

Leider hat dies ein Problem verursacht. Ich kann keinen Weg finden, um Hibernate über dieses Mapping zu informieren, was bedeutet, dass HQL-Abfragen keine Joins durchführen können. Ich würde wirklich gerne eine HQL-Abfrage erstellen, die so aussieht:

SELECT Benutzer FROM SystemEvent Ereignis join Benutzer neueBenutzer where Ereignis.eventType = 'Anmelden'

Allerdings hat Hibernate keine Kenntnis über die Beziehung zwischen SystemEvent und Benutzern, und soweit ich das beurteilen kann, gibt es keine Möglichkeit, es ihm mitzuteilen.

Also hier ist meine Frage: Gibt es einen Weg, Hibernate über eine Beziehung zu informieren, wenn Ihre Domänenobjekte sich über ID-Nummern und nicht über Klassenreferenzen referenzieren?

4voto

RKitson Punkte 2002

Zunächst einmal, wenn Sie eine Spalte mit einem Namen wie 'eventType' haben, sprechen Sie über eine Diskriminatorsäule.

Zweitens besteht ein Großteil der Leistung/Bequemlichkeit, die ein ORM bietet, darin, mit Ihren Geschäftsobjekten und nicht mit Ihrer Datenbank interagieren zu können.

Ich würde mir das Kapitel zur Vererbung in den Hibernate-Dokumentationen ansehen.

Wenn Sie können, würde ich eine abstrakte Klasse namens SystemEvent einrichten, die, basierend auf Ihrem obigen Beispiel, nur eine ID hätte. Jede konkrete Implementierung würde das spezifische Feld/Eigenschaft für das 'relatedObject' enthalten. Ich verwende in der Regel eine 'Tabelle pro Klasse' oder 'Tabelle pro Unterklasse'-Mapping für diese Art von Szenario.

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class SystemEvent {
   @Id @GeneratedValue
   public int eventId;
}

@Entity
@PrimaryKeyJoinColumn(name="event_id")
public class SignupEvent extends SystemEvent {
   @Column(name="user_id")
   public User user;
}

@Entity
@PrimaryKeyJoinColumn(name="event_id")
public class OtherEvent extends SystemEvent {
   @Column(name="other_id")
   public OtherAssociatedObject otherAssociatedObject;
}

Sie würden Ihre HQL wie folgt ändern:

SELECT Benutzer von SignupEvent Ereignis beitreten Benutzer

Lassen Sie mich wissen, wenn Sie möchten, dass ich einen Teil dieser Antwort genauer erläutere.

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