Ошибка Eclipse при сопоставлении с @EmbeddedId

У меня есть объект с составным ключом, поэтому я использую аннотации @Embeddable и @EmbeddedId. Встраиваемый класс выглядит так:

@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {

  @ManyToOne
  @JoinColumn(name = "admin_id")
  private DitaAdmin admin;

  @ManyToOne
  @JoinColumn(name = "account_id")
  private DitaAccount account;

  //constructor, getters, setters...
}

И объект, который его использует:

@Entity
public class DitaAdminAccountSkill {

  @EmbeddedId
  private DitaAdminAccountSkillPK id;

  //constructor, getters, setters...
}

Теперь я хочу сопоставить объект с другим объектом следующим образом:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.admin")
private List<DitaAdminAccountSkill> accountSkills;

Обратите внимание на mappedBy = "id.admin", который ссылается на поле admin в DitaAdminAccountSkillPK, используя поле id в < b>DitaAdminAccountSkill.

Это компилируется и работает нормально. Однако в eclipse отображается сообщение об ошибке: В атрибуте «accountSkills» значение «сопоставлено» «id.admin» не может быть преобразовано в атрибут целевого объекта.

Обратите внимание, что это Проблема JPA, означающая, что аспект JPA жалуется. Теперь я знаю, что мог бы использовать вместо этого @IdClass, но мне просто интересно, почему он считает это ошибкой. А может быть, я делаю что-то ужасно неправильное?


person user1622058    schedule 24.08.2012    source источник


Ответы (5)


Согласно разделу 11.1.15 Спецификация JPA 2.0: Сопоставления отношений, определенные во встроенном классе id, не поддерживаются. Однако это может поддерживаться используемой реализацией JPA. , даже если он официально не поддерживается самим стандартом.

Если это так, вы можете отключить проверку для этого в Eclipse в разделе Window -> Preferences -> Java Persistence -> JPA -> Errors/Warnings -> Attributes -> Cannot resolve attribute name.

person Ivar Wedøe    schedule 24.08.2012
comment
Есть ли способ сделать это, поддерживаемый спецификацией JPA 2.0? - person FGreg; 22.01.2013
comment
Ответил на мой собственный вопрос. Раздел 2.4.1.3 спецификации JPA 2.0 (найдено здесь) приведен ряд очень полезных примеров для этого сценария. Мое решение состояло в том, чтобы использовать @EmbeddedID вместе с @MapsId. - person FGreg; 23.01.2013
comment
Найдено дружественное к JPA 2.0 решение: stackoverflow.com/ вопросы/10078224/ - person Daniel Hári; 25.05.2015

В моем случае проблема не была решена, пока я не установил следующее значение Ignore:

Project Facets > JPA > Errors/Warnings > Type > Mapped Java Class is a member class
person CodeMed    schedule 24.10.2014

Думал, что опубликую решение, которое я нашел, которое соответствует спецификации JPA 2.0 и, похоже, работает так же.

Во-первых, спецификацию JPA 2.0 можно найти здесь: JSR-000317 Спецификация сохраняемости для Eval 2.0 Eval. Соответствующим разделом будет 2.4.1 «Первичные ключи, соответствующие производным идентификаторам».

Вот пример использования указанных вами классов:

Класс встроенного идентификатора:

@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {

    //No further annotations are needed for the properties in the embedded Id.

    //Needs to match the type of the id of your DitaAdmin object. I added 'Id' to the end of the property name to be more explicit.
    //Making the assumption here that DitaAdmin has a simple Integer primary key.
    private Integer adminId;

    //Needs to match the type of the id of your DitaAccount object. I added 'Id' to the end of the property name to be more explicit.
    //Making the assumption here that DitaAccount has a simple Integer primary key.
    private Integer accountId;


    //I'm adding a third property to the primary key as an example
    private String accountName;

    //constructor, getters, setters...

    //hashCode() and equals() overrides
}

"Зависимый" класс сущности:

@Entity
public class DitaAdminAccountSkill {

    @EmbeddedId
    //Any overrides to simple Id properties should be handled with an attribute override
    @AttributeOverride(name = "accountName", column = @Column(name = "account_name"))
    private DitaAdminAccountSkillPK id;

    //MapsId refers to the name of the property in the embedded Id
    @MapsId("adminId")
    @JoinColumn(name="admin_id")
    @ManyToOne
    private DitaAdmin admin;

    @MapsId("accountId")
    @JoinColumn(name="account_id")
    @ManyToOne
    private DitaAccount account;

    //constructor, getters, setters...
}

"Родительский" класс сущности:

public class DitaAdmin {

    @Id
    private Integer id;

    //...

    //Now your mappedBy attribute can refer to the admin object defined on DitaAdminAccountSkill which is also part of the Primary Key
    @OneToMany(fetch = FetchType.LAZY, mappedBy="admin")
    private List<DitaAdminAccountSkill> accountSkills;

    //...
}
person FGreg    schedule 22.01.2013
comment
С этими обоими параметрами (mappedBy=id.admin или mappedBy=admin).. когда я пытаюсь сопоставить неленивую коллекцию, я получаю следующую ошибку. Ошибка: resql.util.PSQLException: ОШИБКА: столбец workflowst0_.stepseqno не существует. Пожалуйста, посмотрите stackoverflow .com/questions/23312951/ . Заранее спасибо. - person Channa; 26.04.2014

Прежде чем пытаться использовать какое-либо из предыдущих решений, сначала проверьте свой persistence.xml и убедитесь, что либо exclude-unlisted-classes установлено на true, либо что все ваши сопоставленные классы перечислены в вашем persistence-unit.

person Andres Felipe    schedule 16.03.2015

Настройки -> Сохранение Java -> JPA -> Ошибки/предупреждения -> Атрибут -> Классы Embedded ID не должны содержать сопоставления отношений: (игнорировать)

person stakahop    schedule 25.09.2015