web-dev-qa-db-fra.com

Pourquoi mon EmbeddedId dans hibernate ne fonctionne-t-il pas?

J'ai une clé primaire composée (IDHOLIDAYPACKAGE, IDHOLIDAYPACKAGEVARIANT) dans la table HolidayPackageVariantIDHOLIDAYPACKAGE se réfère à l'entité HolidayPackage avec un Plusieurs à Un relation entre HolidayPackageVariant et HolidayPackage .

Lorsque j'essaie de faire le mappage PK Compund dans HolidayPackageVariant, j'obtiens le message d'erreur suivant:

Création de la SessionFactory initiale failed.org.hibernate.annotations.common.AssertionFailure: la classe déclarante est introuvable dans la hiérarchie de l'état d'héritage: org.wah.model.holidaypackage.HolidayPackageVariantPrimaryKey

Quelqu'un peut-il s'il vous plaît me dire ce que je fais mal ici?

Mes POJOs ressemblent à ceci:

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
}

Forfait Vacances

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
}
20
brainydexter

Vous ne devriez pas avoir le @Id dans la classe EmbeddedId. Supprimez l'annotation Id dans votre HolidayPackageVariantPrimaryKey et cela devrait fonctionner correctement. 

81
Kiran

Je me suis déjà battu avec @EmbeddedId et j'ai fini d'atteindre le même objectif avec @IdClass. La différence est que, lorsque vous utilisez @IdClass, vous ne l'utilisez pas dans la définition de classe, mais vous redéclarez les mêmes champs (toutefois, j'ai alors des getters/setters directs pour les champs id, ce qui est plus confortable pour moi).

Voici mon exemple de projet que j'utilise pour traiter une base de données d'adresses librement disponible de l'institution gouvernementale polonaise GUS:

La clé composite:

@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;
    }
}

La classe l'utilisant (comté):

@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;
    }
}

La classe composant la clé composite (province):

@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;
    }
}
2
Danubian Sailor

Appliqué à un champ persistant ou à la propriété d'une classe d'entité ou d'une superclasse mappée pour désigner une clé primaire composite qui est une classe incorporable. La classe incorporable doit être annotée comme étant incorporable. Il ne doit y avoir qu'une seule annotation EmbeddedId et aucune annotation Id lorsque l'annotation EmbeddedId est utilisée.

L'annotation AttributeOverride peut être utilisée pour remplacer les mappages de colonnes déclarés dans la classe intégrable.

L'annotation MapsId peut être utilisée conjointement avec l'annotation EmbeddedId pour spécifier une clé primaire dérivée.

Si l'entité a une clé primaire dérivée, l'annotation AttributeOverride ne peut être utilisée que pour remplacer les attributs de l'ID incorporé qui ne correspondent pas à la relation avec l'entité parent.

0
Ajay