Hibernate 为相同的代码生成不同的查询

Hibernate generates different queries for same code

我们刚刚修复了 Hibernate 中的一个行为,在该行为中,它在本地计算机上生成的查询与在登台服务器上生成的查询不同。谁能给我解释一下,为什么

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

在本地翻译成

from
user_password abstractpa0_
left outer join user_account basicaccou1_ on abstractpa0_.user_id=basicaccou1_.id

在服务器上,运行 dockerized on Kubernetes,它被翻译成

from user_password abstractpa0_
left outer join d21_user_account useraccoun1_ on abstractpa0_.user_id = useraccoun1_.id
left outer join user_account useraccoun1_1_ on useraccoun1_.id = useraccoun1_1_.id

我们使用单一的 table 继承策略。基数 class 是 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)

和工作人员 classes.

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

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

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

我们可以通过将 AbstractPasswordEntity 中的关系注释更改为

经过一天的错误修复和大量 WTF 来修复该行为
@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()

这现在可以在所有环境中以相同的方式编译和执行。我唯一没有的是对刚刚发生的事情和原因的理解。

Funfact:与 pkgdiff 和 md5deep 相比,暂存和本地的 jar 显示完全相同的结果 - 除了 GitLab 属性。

由于该主题无法获得任何回复,以下是我们的最佳猜测:

这是泛型的问题。它们在 运行 时间被删除,我们 运行 陷入排序问题。在本地它是 运行s,因为偶然地,hibernate 中 classes 的顺序导致了预期的结果。在暂存时,顺序会混淆,hibernate 使用第一个拟合 class 作为泛型,然后导致执行不同的查询。因此明确指定父 BasicAccountEntity 作为入口点确实解决了这个问题。

正如我所说,最好的猜测。