2013-01-10 12 views
7

Ich verwende Hibernate und Anmerkungen für ORM. Ich habe Schnittstellen für alle Beans und ich verwende targetEntity für Beziehungen: Hibernate kann den Typ nicht ableiten, da der Getter eine Schnittstelle und nicht eine Bean zurückgibt.Override @ManyToOne targetEntity für @Embedded mit Schnittstellen

Ich bekomme eine MappingException (Typ konnte nicht ermittelt werden) für eingebettete Beans.

@Entity(name="FieldBean") 
public class FieldBean implements Field { 
    ... 
} 

@Embeddable 
public class FacetBean implements Facet { 
    ...  

    @ManyToOne(targetEntity = FieldBean.class) 
    @JoinColumn(name = "field_id") 
    public Field getField() { 
     return field; 
    } 

} 

@Entity(name = "Chart") 
public class ChartBean implements Chart { 

    @Embedded 
    @AssociationOverride(
     name = "field", 
     joinColumns = @JoinColumn(name = "category_facet_field_id") 
    ) 
    public Facet getCategoryFacet() { 
     return categoryFacet; 
    } 

} 

Ich erhalte die MappingException: Typen kann nicht bestimmen für: Field, bei Tisch: Diagramm für Spalten: [org.hibernate.mapping.Column (Feld)]

Mit Bohnen anstelle von Schnittstellen für Property- und Getter/Setter-Deklarationen lösen das Problem, aber ich möchte bei der Verwendung von Schnittstellen bleiben. Die Verwendung von Beans für Eigenschaftsdeklarationen allein löst das Problem nicht.

Kann mir jemand in die richtige Richtung zeigen?

Antwort

0

Meine Vergangenheit mit jpa sagte mir, nicht Vererbung zu verwenden. Keine zugeordneten Oberklassen, keine Schnittstellen, etc ... einfach Entitäten mit Mitgliedern. Ich habe mit Hibernate und Eclipselink gearbeitet und beide haben wirklich, wirklich Probleme mit der Vererbung. Es ist schwierig, eine Persistenzschicht mit jpa zu schreiben, die mehr als einen Provider unterstützt, da all diese Provider so viele Bugs haben. halte es so einfach wie möglich. Verwenden Sie keine "speziellen" Funktionen. Ich versichere Ihnen, wenn Sie versuchen, den Anbieter zu wechseln oder einfach eine Software auf verschiedenen Anwendungsservern wie jboss (hibernate) oder glassfish/weblogic (eclipse/top link) laufen zu lassen, können Sie froh sein, wenn Sie eine möglichst einfache Persistenzschicht verwenden Funktionen wie möglich. Ich weiß nicht, ob das ein Fehler ist, aber ich nehme an, dass es ist.

+0

Ich bin mit Schnittstellen und Vererbung. Zugegeben, dies führte zu einer gewissen Komplexität auf der Ebene des ORM. Auf der anderen Seite liefert es mir die Ebene der Abstraktion, nach der ich suche. – user1966634

+0

** Schnittstellen ** dienen zur Abstraktion der ORM-Technologie. Unter Verwendung eines MDA-Ansatzes erzeuge ich den Code der Persistenzschicht aus einem Objektmodell, einschließlich Schnittstellen, Beans und Serviceklassen. Eine alternative ORM-Technologie könnte transparent verwendet werden, indem die Schnittstellen stabil gehalten werden, aber alternative Beans und Serviceklassen erzeugt werden. – user1966634

+0

** Vererbung ** wird aus der Datenmodellierungsperspektive benötigt, um sowohl die allgemeine als auch die spezifische Sicht auf die Daten zu unterstützen, insbesondere, aber nicht ausschließlich, auf der relationalen Datenbankebene. Trotz einiger Nachteile bleibt das Feature nützlich und vereinfacht Code auf höheren Ebenen im Anwendungsstapel. – user1966634

1

Ich habe eine funktionierende Lösung für eine Weile verwendet, aber es enthält eine kleine Fall von Vendor Lock-in. Ich habe keine Möglichkeit gefunden, dies nur mit JPA-Annotationen zu tun, aber es gibt eine Hibernate-spezifische Annotation @Target, die den Trick macht. Ich habe etwas wie Sie getan, mit den erwarteten Ergebnissen. Allerdings habe ich Ihre anderen Anmerkungen nicht verwendet, so kann ich nicht garantieren, dass es so funktioniert, wie Sie es erwarten.

seltsam Nichts in den Fähiges Klassen los:

public interface PointsInt extends Serializable { 
    int offensivePoints(); 

    int defensivePoints(); 

} 

@Embeddable 
public class Points implements PointsInt { 
    private int def; 
    private int off; 
    public int offensivePoints() { return off; } 

    public int defensivePoints() { return def; } 

} 

Aber in der verzehr Klasse verwenden wir Hibernate @Target:

import javax.persistence.*; 
import org.hibernate.annotations.Target; 

@Entity 
public class Series extends LongIdEntity implements Serializable { 

    @Embedded 
    @Target(Points.class) 
    private PointsInt points; 
    // I prefer to declare my annotations on fields rather than methods 
} 

Ergebnis:

mysql> describe series; 
+-----------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+-----------------+-------------+------+-----+---------+----------------+ 
| id    | bigint(20) | NO | PRI | NULL | auto_increment | 
| def    | int(11)  | YES |  | NULL |    | 
| off    | int(11)  | YES |  | NULL |    | 
+-----------------+-------------+------+-----+---------+----------------+ 
3 rows in set (0.12 sec)