Hibernate генерирует разные запросы для одного и того же кода

#hibernate #spring-data-jpa

Вопрос:

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

 @NotNull
@OneToOne(fetch = FetchType.EAGER)
@Type(type = "user_account")
open var user: T
 

переводится локально на

из
user_password abstractpa0_
слева внешнее соединение с учетной записью пользователя basicaccou1_ на abstractpa0_.user_id=basicaccou1_.id

и на сервере, работающем в докеризованном режиме на Kubernetes, он переводится в

из user_password abstractpa0_
слева внешнее соединение d21_user_account useraccoun1_ на abstractpa0_.идентификатор пользователя = useraccoun1_.id
слева внешнее соединение user_account useraccoun1_1_ на useraccoun1_.id = useraccoun1_1_.id

Мы используем стратегию наследования одной таблицы. Базовый класс-это AbstractPasswordEntity

 @Entity(name = "user_password")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "user_type")
abstract class AbstractPasswordEntity<T : BasicAccountEntity>(

    ...

    @NotNull
    @OneToOne(fetch = FetchType.EAGER)
    @Type(type = "user_account")
    open var user: T

) : BaseEntity()
 

который внедряется Заказчиком

 @Entity(name = "CustomerPassword")
@DiscriminatorValue("CustomerPasswordEntity")
class CustomerPasswordEntity(

    id: Long? = null,
    passwordHash: String,
    user: CustomerAccountEntity

) : AbstractPasswordEntity<CustomerAccountEntity>(..., user)
 

и занятия для персонала.

 @Entity(name = "StaffPassword")
@DiscriminatorValue("StaffPasswordEntity")
class StaffPasswordEntity(

    id: Long? = null,
    passwordHash: String,
    user: StaffAccountEntity

) : AbstractPasswordEntity<StaffAccountEntity>(..., user)
 

Мы могли бы исправить поведение после дня исправления ошибок и множества ошибок, изменив аннотацию отношений на AbstractPasswordEntity

 @Entity(name = "user_password")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "user_type")
abstract class AbstractPasswordEntity<T : BasicAccountEntity>(

    ...

    @NotNull
    @OneToOne(fetch = FetchType.EAGER, targetEntity = BasicAccountEntity::class)
    open var user: T

) : BaseEntity()
 

Теперь это компилируется и выполняется во всех средах одинаково. Единственное, чего у меня нет, — это понимания того, что только что произошло и почему.

Эффект: Банки из промежуточного и локального, по сравнению с pkgdiff и md5deep, показали точно такой же результат — за исключением свойств GitLab.

Ответ №1:

Поскольку на эту тему не удалось получить никаких ответов, вот наше лучшее предположение:

Это проблема с дженериками. Они удаляются во время выполнения, и мы сталкиваемся с проблемой сортировки. Локально он запускается, потому что случайно порядок классов в hibernate приводит к ожидаемому результату. При промежуточном размещении порядок путается, hibernate использует первый подходящий класс для универсального, что затем приводит к выполнению другого запроса. Таким образом, явное указание родителя BasicAccountEntity в качестве точки входа решило эту проблему.

Как я уже сказал, лучше всего догадаться.