Подтвердить что ты не робот

Почему мой EmbeddedId в спящем режиме не работает?

У меня есть основной первичный ключ (IDHOLIDAYPACKAGE, IDHOLIDAYPACKAGEVARIANT) в таблице HolidayPackageVariant, где IDHOLIDAYPACKAGE относится к сущности HolidayPackage с отношением Много к Один между HolidayPackageVariant и HolidayPackage.

Когда я пытаюсь выполнить компиляцию PK в HolidayPackageVariant, я получаю следующую ошибку:

Начальное создание SessionFactory failed.org.hibernate.annotations.common.AssertionFailure: Объявление класс не найден в иерархии состояний наследования: org.wah.model.holidaypackage.HolidayPackageVariantPrimaryKey

Может кто-нибудь, пожалуйста, скажите мне, что я делаю неправильно здесь?

MY 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
}
4b9b3361

Ответ 1

Вы не должны иметь @Id в классе EmbeddedId. Удалите аннотацию Id в HolidayPackageVariantPrimaryKey, и она будет работать нормально.

Ответ 2

Я сражался один раз с @EmbeddedId, и я закончил достижение той же цели с помощью @IdClass. Разница заключается в том, что при использовании @IdClass вы не используете его в определении класса, но вы переопределяете те же поля (однако у меня есть прямые геттеры/сеттеры для полей id, что для меня более удобно).

Вот мой пример, из проекта, который я использую для обработки свободно доступной адресной базы данных из польского государственного учреждения 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;
    }
}

Класс, использующий его (county):

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

Ответ 3

Применяется к постоянному полю или свойству класса сущности или сопоставленного суперкласса для обозначения составного первичного ключа, который является вложенным классом. Встраиваемый класс должен быть аннотирован как Embeddable. Должна быть только одна вставка EmbeddedId и аннотация Id, когда используется аннотация EmbeddedId.

Аннотации AttributeOverride могут использоваться для переопределения сопоставлений столбцов, объявленных внутри вложенного класса.

Аннотации MapsId могут использоваться вместе с аннотацией EmbeddedId для указания производного первичного ключа.

Если объект имеет производный первичный ключ, аннотация AttributeOverride может использоваться только для переопределения тех атрибутов встроенного идентификатора, которые не соответствуют отношению к родительскому объекту.