Hibernate генерирует неправильный первичный ключ

#java #spring-boot #hibernate #spring-data-jpa #spring-test

#java #spring-boot #гибернация #spring-data-jpa #spring-тест

Вопрос:

У меня есть объект Hibernate.

 @AllArgsConstructor @NoArgsConstructor @Getter
@Entity
@Table(name = "app_category_link", schema = "mariott_application")
public class AppCategory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "app_category_link_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "app_id")
    private App app;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id")
    private Category category;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id_who_added")
    private User userWhoAdded;

    @Column(name = "date_add")
    private ZonedDateTime dateAdded;
}
  

И у меня есть @DataJpaTest , который сгенерировал такой DDL. Удивительно, но он выдает неожиданный первичный ключ.

 create table mariott_application.app_category_link
(
    app_category_link_id int8      not null,
    date_add             timestamp,
    app_id               bigserial not null,
    category_id          int8      not null,
    user_id_who_added    int8,
    primary key (app_id, category_id)     -- wrong
)
  

Почему Hibernate генерирует неправильный первичный ключ?

Комментарии:

1. Возможно ли, что вы используете это имя таблицы и для других сопоставлений? Кроме того, какую версию вы используете?

2. Это имя таблицы уникально. Я использую гибернацию 5.4.18.Final с весенней загрузкой 2.3.2.RELEASE

3. Можете ли вы выполнить отладку, org.hibernate.mapping.Table#setPrimaryKey чтобы понять, почему это установлено?

4. Думаю, я нашел проблему. У меня есть ManyToMany связь между App и Category . Ссылки AppCategory#app и AppCategory#category являются ненаправленными. Я думаю, именно поэтому Hibernate переопределяет первичный ключ (app_id, category_id) во время второго прохода

Ответ №1:

Это может произойти, когда вы используете имя таблицы несколько раз, например, также в @JoinTable / @CollectionTable . Всегда используйте существующую сущность как обратную @OneToMany , а не определяйте @ManyToMany ассоциацию, чтобы избежать этой проблемы.