Таблица 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. Создайте статический внутренний класс как тип первичного ключа, который будет менее навязчивым.

Другие вопросы по тегам