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
作为入口点确实解决了这个问题。
正如我所说,最好的猜测。
我们刚刚修复了 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
中的关系注释更改为
@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
作为入口点确实解决了这个问题。
正如我所说,最好的猜测。