Таблица JPA с 2 полями первичного ключа
У меня есть таблица, которая содержит только 2 поля. Таблица имеет составной ПК, образованный этими двумя полями.
При использовании NetBeans для создания объектов EJB из базы данных объект EJB не создается автоматически, как другие таблицы, имеющие более 2 полей.
Так что я думаю, мне нужно создать бин сущности сам. Какова лучшая практика для создания этого объекта? Должен ли он содержать COMPOSITE KEY
объект или нет?
2 ответа
Я не использую NetBeans, поэтому я не могу ничего сказать о его инструментах отображения.
Для сопоставления составного ключа есть несколько вариантов. Вы можете
Определить отдельный
@Embeddable
объект с полями PK и использовать его как@EmbeddedId
в вашем@Entity
учебный класс@Embeddable public class MyCompositePK { @Column private String fieldA; @Column private String fieldB; } @Entity public class MyBean { @EmbeddedId private MyCompositePK id; @Column private String fieldC; }
Определите неотображенный POJO с полями PK и используйте его как
@IdClass
в@Entity
,@Entity @IdClass(value=ClassAB.ClassABId.class) public class ClassAB implements Serializable { private String idA; private String idB; @Id @Column(name="ID_A") public String getIdA(){ return idA; } public void setIdA(String idA){ this.idA = idA; } @Id @Column(name="ID_B") public String getIdB(){ return idB; } public void setIdB(String idB){ this.idB = idB; } static class ClassABId implements Serializable { private String idA; private String idB; public String getIdA(){ return idA; } public void setIdA(String idA){ this.idA = idA; } public String getIdB(){ return idB; } public void setIdB(String idB){ this.idB = idB; } // implement equals(), hashcode() } }
В этом примере
ClassABId
это статический внутренний класс просто для удобства.
Эти параметры также объясняются в отличном ответе Паскаля Тивента на этот вопрос: как сопоставить составной ключ с Hibernate?,
В этом связанном вопросе обсуждаются различия между этими подходами: какую аннотацию следует использовать: @IdClass или @EmbeddedId. Обратите внимание, что объявление полей дублируется с @IdClass
подход.
Во всяком случае, я не думаю, что есть альтернатива созданию двух классов. Вот почему я задал этот вопрос: отображение класса, который состоит только из составного ПК без @IdClass или @EmbeddedId. Кажется, для этого есть особенность, связанная с гибернацией.
В качестве дополнительного примечания: если у вас есть контроль над структурой БД, вы также можете не использовать составные ключи. Есть несколько причин для этого.
Спасибо @XaviLópez. Ваше объяснение исправило мой код, который был объявлен как собственный IdClass, упомянутый @Tom Anderson. Когда я объявил в качестве своего собственного IdClass, имеющего 2 столбца @Id, запрос JPA, извлекающий список этой сущности, возвращал ожидаемые "n" элементов в списке результатов, но каждый элемент в этом списке является нулевым. Но этот размер "n" ожидается. После перехода к статическому внутреннему классу, который не требует рефакторинга, он может вернуть правильный набор результатов.
По моему мнению: самоссылка на IdClass не будет работать, потому что самость уже является сущностью, и это должно быть в контексте постоянства. Если у меня также есть объект первичного ключа того же типа, то в контексте постоянства будут два "идентичных" объекта. Таким образом, это не должно быть разрешено. Следовательно, мы не должны использовать собственные ссылки @IdClass. Создайте статический внутренний класс как тип первичного ключа, который будет менее навязчивым.