19

Ich habe eine Verbindung Primärschlüssel (IDHOLIDAYPACKAGE, IDHOLIDAYPACKAGEVARIANT) in Tabelle HolidayPackageVariant wo IDHOLIDAYPACKAGE zu EinheitHolidayPackage mit einer Vielen zu Ein Beziehung zwischen HolidayPackageVariant und HolidayPackage bezieht.Warum funktioniert meine EmbeddedId im Ruhezustand nicht?

Wenn ich versuche, die compund PK-Mapping in HolidayPackageVariant zu tun, ich folgende Fehlermeldung erhalten:

Initial SessionFactory creation failed.org.hibernate.annotations.common.AssertionFailure: Declaring class is not found in the inheritance state hierarchy: org.wah.model.holidaypackage.HolidayPackageVariantPrimaryKey

Kann jemand bitte sagen Sie mir, was mache ich hier falsch?

MY POJOs wie folgt aussehen:

HolidayPackageVariant:

@Entity 
@Table(name="HOLIDAYPACKAGEVARIANT") 
public final class HolidayPackageVariant { 

    private HolidayPackageVariantPrimaryKey idCompound; 

    @EmbeddedId 
    public HolidayPackageVariantPrimaryKey getIdCompound() { 
     return idCompound; 
    } 

    // other code 
} 

HolidayPackageVariantPrimaryKey

@Embeddable 
public final class HolidayPackageVariantPrimaryKey implements Serializable { 

    private Integer idHolidayPackageVariant; 
    private HolidayPackage holidayPackage; 

    public HolidayPackageVariantPrimaryKey(){} 

    public HolidayPackageVariantPrimaryKey(int id, HolidayPackage pkg){ 
     setIdHolidayPackageVariant(id); 
     setHolidayPackage(pkg); 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "IDHOLIDAYPACKAGEVARIANT", nullable = false) 
    public Integer getIdHolidayPackageVariant() { 
     return idHolidayPackageVariant; 
    } 

    @Id 
    @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.ALL}) 
    @JoinColumn(name="IDHOLIDAYPACKAGE", nullable=false) 
    public HolidayPackage getHolidayPackage() { 
     return holidayPackage; 
    } 

    // equals and hashCode 
} 

HolidayPackage

public final class HolidayPackage { 
    private Set<HolidayPackageVariant> holidayPackageVariants = new HashSet<HolidayPackageVariant>(0); 

    @OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL}, mappedBy = "idCompound.holidayPackage") 
    public Set<HolidayPackageVariant> getHolidayPackageVariants() { 
     return holidayPackageVariants; 
    } 

    // other code 
} 
+0

Hallo @brainydexter, Könnten Sie bitte die richtige Antwort auf diese Frage ändern? Ich musste es reparieren, dann kam ich zurück und poste die Antwort, nur um zu erkennen, dass es schon da war. – coderatchet

+1

@coderatschet fertig. Danke, dass du es aufgezeigt hast. Da ich nicht mehr Winterschlaf machte, fiel das von meinem Radar ab. – brainydexter

Antwort

77

Sie sollten die @Id in der EmbeddedId Klasse nicht haben. Entfernen Sie die Id Annotation in Ihrem HolidayPackageVariantPrimaryKey und es sollte gut funktionieren.

+4

arbeiten zu lassen. Dieses reparierte mein Problem auch. Ich denke, dies sollte als die Antwort anstelle der vorherigen markiert werden. – Jalpesh

+2

Scheint wie das ist die richtige Antwort –

+0

Aber was würde ich tun, z.B. wenn ich ein Mitglied 'private Long id;' in meinem '@ Embedded' haben möchte, um jedes Mal einen automatischen Wert zu erhalten, wenn ich ein Element einfüge? Das ist [was ich gerade nicht bekomme] (http://stackoverflow.com/questions/29976363/hibernate-generatedvalue-in-embedded-always-null) ... – displayname

2

Ich habe mit @EmbeddedId einmal gekämpft, und ich habe zu erreichen das gleiche Ziel abgeschlossen mit @IdClass. Der Unterschied ist, wenn Sie @IdClass verwenden, verwenden Sie es nicht in der Klassendefinition, aber Sie redeclare die gleichen Felder (jedoch habe ich dann direkte Getter/Setter für ID Felder, die für mich bequemer ist).

Hier ist mein Beispiel aus Projekt verwenden, um ich frei verfügbare Adressdatenbank von polnischer Regierungsinstitution GUS zu verarbeiten:

Verbundschlüssel:

@Embeddable 
class GusPowiatPK implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private Short powiatNr; 
    private GusWojewodztwo wojewodztwo; 

    @Column(name = "POW_NR") 
    public Short getPowiatNr() { 
     return powiatNr; 
    } 

    public void setPowiatNr(Short powiatNr) { 
     this.powiatNr = powiatNr; 
    } 

    @ManyToOne 
    @JoinColumn(name = "WOJ_ID") 
    public GusWojewodztwo getWojewodztwo() { 
     return wojewodztwo; 
    } 

    public void setWojewodztwo(GusWojewodztwo wojewodztwo) { 
     this.wojewodztwo = wojewodztwo; 
    } 
} 

Die Klasse mit ihm (Grafschaft):

@Entity 
@Table(name = "POWIAT") 
@IdClass(GusPowiatPK.class) 
public class GusPowiat { 

    private Short powiatNr; 
    private GusWojewodztwo wojewodztwo; 
    private String nazwa; 
    private Date stanNa; 
    private boolean powiatMiejski; 

    public GusPowiat() { 
     super(); 
    } 

    public GusPowiat(Short powiatNr, GusWojewodztwo wojewodztwo) { 
     super(); 
     this.powiatNr = powiatNr; 
     this.wojewodztwo = wojewodztwo; 
    } 

    @Id 
    public Short getPowiatNr() { 
     return powiatNr; 
    } 

    public void setPowiatNr(Short powiatNr) { 
     this.powiatNr = powiatNr; 
    } 

    @Id 
    public GusWojewodztwo getWojewodztwo() { 
     return wojewodztwo; 
    } 

    public void setWojewodztwo(GusWojewodztwo wojewodztwo) { 
     this.wojewodztwo = wojewodztwo; 
    } 

    @Column(name = "NAZWA", length = 50, nullable = false) 
    public String getNazwa() { 
     return nazwa; 
    } 

    public void setNazwa(String nazwa) { 
     this.nazwa = nazwa; 
    } 

    @Temporal(TemporalType.DATE) 
    @Column(name = "STAN_NA", nullable = false) 
    public Date getStanNa() { 
     return stanNa; 
    } 

    public void setStanNa(Date stanNa) { 
     this.stanNa = stanNa; 
    } 

    @Column(name = "POW_MIEJSKI") 
    public boolean isPowiatMiejski() { 
     return powiatMiejski; 
    } 

    public void setPowiatMiejski(boolean powiatMiejski) { 
     this.powiatMiejski = powiatMiejski; 
    } 
} 

Die Klasse Komponieren Verbundschlüssel (Provinz):

@Entity 
@Table(name = "WOJEWODZTWO") 
public class GusWojewodztwo { 

    private Short id; 
    private String nazwa; 
    private Date stanNa; 

    public GusWojewodztwo() { 
     super(); 
    } 

    public GusWojewodztwo(Short id) { 
     super(); 
     this.id = id; 
    } 

    @Id 
    @Column(name = "WOJ_ID") 
    public Short getId() { 
     return id; 
    } 

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

    @Column(name = "NAZWA", length = 50, nullable = false) 
    public String getNazwa() { 
     return nazwa; 
    } 

    public void setNazwa(String nazwa) { 
     this.nazwa = nazwa; 
    } 

    @Temporal(TemporalType.DATE) 
    @Column(name = "STAN_NA", nullable = false) 
    public Date getStanNa() { 
     return stanNa; 
    } 

    public void setStanNa(Date stanNa) { 
     this.stanNa = stanNa; 
    } 
} 
+0

Ich verstehe es nicht, warum sollte ich IDClass verwenden, da ich die gleichen Felder in der Klasse neu definieren müssen. Ich hatte gehofft, es mit EmbeddedId – brainydexter

0

Anwenden auf ein persistentes Feld oder eine Eigenschaft einer Entitätsklasse oder einer zugeordneten übergeordneten Klasse, um einen zusammengesetzten Primärschlüssel anzugeben, der eine einbettbare Klasse darstellt. Die embeddable-Klasse muss als Embeddable annotiert werden. Es darf nur eine EmbeddedId-Annotation und keine ID-Annotation geben, wenn die Annotation EmbeddedId verwendet wird.

Die Annotation AttributeOverride kann zum Überschreiben der Spaltenzuordnungen verwendet werden, die in der embeddable-Klasse deklariert sind.

Die Annotation MapsId kann zusammen mit der Annotation EmbeddedId verwendet werden, um einen abgeleiteten Primärschlüssel anzugeben.

Wenn die Entität einen abgeleiteten Primärschlüssel hat, darf die AttributeOverride-Annotation nur zum Überschreiben der Attribute der eingebetteten ID verwendet werden, die nicht der Beziehung zur übergeordneten Entität entsprechen.

Verwandte Themen