Frage

Ich habe ein paar Domain-Modell-Klassen in meiner Web-Anwendung, die eine hierarchische Beziehung zu sich selbst hat. Ein Beispiel ist die hierarchische zu klassifizieren Anwender Buchungen verwendete Kategoriestruktur.

Es gibt eine gewisse Logik auf die hierarchische Natur dieser Klassen beziehen, die üblich ist. Also habe ich versucht, die Logik in eine generische @ MappedSuperclass kommentierte Super zu bewegen.

So etwas wie:

@MappedSuperclass
public abstract class HierarchicalBaseEntity<N extends HierarchicalBaseEntity<N>>
        extends BaseEntity {

    @ManyToOne(optional=true)
    @JoinColumn(name="parent")
    private N parent;

    private int depth;

    public N getParent() { ...
    public void setParent(N newParent) { ...

    public boolean isRoot() { ...
    public int getDepth() { ...

    public boolean isDescendantOf(N ancestor) { ...
    public static <N extends HierarchicalBaseEntity<N>> N getCommonAncestor(N a, N b) { ...
    public static <N extends HierarchicalBaseEntity<N>> Collection<N> reduceToCommonAncestors(Collection<N> entities) { ...
}

Die Unterklassen erstrecken sich dann HierarchicalBaseEntity sich als gattungs N geben:

@Entity
public class CategoryBean extends HierarchicalBaseEntity<CategoryBean> {

In Java das alles funktioniert ganz sauber aus. Aber leider Eclipse nicht scheint nicht das generische ‚Eltern‘ Feld zu mögen:

private N parent;

Es gibt folgende Ausnahme:

Caused by: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException
Exception Description: [class net.timp.yaase.core.model.HierarchicalBaseEntity] uses a non-entity [class java.lang.String] as target entity in the relationship attribute [field parent].
at org.eclipse.persistence.exceptions.ValidationException.nonEntityTargetInRelationship(ValidationException.java:1341)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.RelationshipAccessor.getReferenceDescriptor(RelationshipAccessor.java:416)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:609)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:678)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:107)

Warum ist es beschweren sich über eine Nicht-Einheit String?

Als Test habe ich versucht, die Generika zu entfernen und nur das übergeordnete Feld mit wie folgt definiert:

private HierarchicalBaseEntity parent;

Ohne Generika, Eclipse gab diese Ausnahme:

Caused by: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.ValidationException
Exception Description: [class net.timp.yaase.core.model.OnymBean] uses a non-entity [class net.timp.yaase.core.model.HierarchicalBaseEntity] as target entity in the relationship attribute [field parent].
at org.eclipse.persistence.exceptions.ValidationException.nonEntityTargetInRelationship(ValidationException.java:1341)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.RelationshipAccessor.getReferenceDescriptor(RelationshipAccessor.java:416)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:609)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:678)
at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:107)

True HierarchicalBaseEntity sein nicht ein Entity in jedem Fall ist ein @ MappedSuperclass .. aber ist es eine Möglichkeit, dies mit Generika oder auf andere Weise zu tun? Es scheint, dass Sie nicht ein Feld in Ihrem @ MappedSuperclass haben können, dass Verweis einer seiner Unterklasse.

War es hilfreich?

Lösung

Das Problem ist, dass, wenn Generics als Feldtypen für Beziehungen mit Eclipselink kann nicht wissen, was die Zielart erst zur Laufzeit ist, wenn die tatsächliche Instanz kontrolliert wird. So ist die Zuordnung würde zur Laufzeit dynamisch erstellt werden muß, und dies wird nicht unterstützt.

Sie könnten auch weiterhin das Generic Oberklasse verwenden, aber dies würde erfordern, um das Feld zu den Entitäten zu bewegen, wo sie Typen definiert haben müßten dann abstrakt internen Getter / Setter für die Felder, die Rückkehr Objekt, dass die generischen Methoden, um die generischen Gießen nennen würden Art. Verworren, aber es wäre für den Generic MappedSuperclass ermöglichen.

Andere Tipps

Ich glaube, ich bin zu spät, aber die Leute für die Antwort auf dieses Problem suchen (wie ich) sollten einen Blick auf diese: https://bugs.eclipse.org/bugs/show_bug.cgi?id= 312.132

Der andere Anbieter, die generische Art in einer dauerhaften Beziehung unterstützt, ist OpenJPA . Die Annahme OpenJPA macht, ist, dass das generische Typ-Feld ein hartnäckiger Typ ist und mit einem (OpenJPA spezifisch) als solche mit Anmerkungen versehen werden @Type Anmerkung.

Diese @Type Anmerkung fungiert als Platzhalter für OpenJPA Mapping-Engine und hält eine Abbildung in der Referenz eine persistente Identität der Laufzeitinstanz ist. Vor vielen Jahren schrieb ich ein Blog ; Ich nenne es hier wieder nicht für Eigenwerbung, aber der Hoffnung, es könnte einige Wege zeigen, für Sie einen generischen Baum zu unterstützen, ohne die konkrete Art Informationen nach unten eine Art Hierarchie nach unten zu drücken, die (und dadurch verlieren die Essenz der generic-basierten Typ-Modell ).

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