为什么我的EmbeddedId在休眠状态下不起作用?

时间:2012-03-29 10:31:41

标签: java hibernate jpa hibernate-annotations composite-primary-key

我在表格(IDHOLIDAYPACKAGE, IDHOLIDAYPACKAGEVARIANT)中有一个复合主键HolidayPackageVariant,其中IDHOLIDAYPACKAGE指实体 HolidayPackage ,其中很多到< strong> HolidayPackageVariant HolidayPackage 之间的一个关系。

当我尝试在HolidayPackageVariant中进行compund PK映射时,出现以下错误:

  

创建初始SessionFactory   failed.org.hibernate.annotations.common.AssertionFailure:声明   在继承状态层次结构中找不到类:   org.wah.model.holidaypackage.HolidayPackageVariantPrimaryKey

有人可以告诉我这里我做错了什么吗?

我的POJO看起来像这样:

  

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
}

3 个答案:

答案 0 :(得分:82)

@Id班级不应该有EmbeddedId。删除Id中的HolidayPackageVariantPrimaryKey注释,它应该可以正常工作。

答案 1 :(得分:2)

我与@EmbeddedId打过一次,我用@IdClass完成了同样的目标。不同之处在于,当你使用@IdClass时,你没有在类定义中使用它,但是你重新声明了相同的字段(但是,我有直接的id字段的getter / setter,这对我来说更舒服)

这是我的例子,来自我用来处理来自波兰政府机构GUS的免费地址数据库的项目:

复合键:

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

使用它的类(县):

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

构成复合键(省)的类:

@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 :(得分:0)

应用于实体类或映射超类的持久字段或属性,以表示作为可嵌入类的复合主键。可嵌入类必须注释为Embeddable。 使用EmbeddedId注释时,必须只有一个EmbeddedId注释而没有Id注释。

AttributeOverride注释可用于覆盖在embeddable类中声明的列映射。

MapsId注释可以与EmbeddedId注释结合使用,以指定派生主键。

如果实体具有派生主键,则AttributeOverride注释可能仅用于覆盖嵌入式ID的那些与父实体的关系不对应的属性。