我有一个Sping Boot 3.1.1 / Hibernate 6.2应用程序,它使用以下驱动程序连接到Oracle 12 c数据库:
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
字符串
此应用程序具有以下存储库接口和类:
public interface SomeEntityRepository extends Repository<SomeEntity, SomeEntityId> {
@Query("""
FROM SomeEntity
WHERE id = :id
AND description is not null
""")
Optional<SomeEntity> find(SomeEntityId id);
}
x
@Embeddable
public class SomeEntityId {
private Long idX;
private Long idY;
private Long idZ;
}
@Entity
public class SomeEntity {
@EmbeddedId
private SomeEntityId id;
private String description;
}
的字符串
当执行find
查询时,Hibernate 6.2将JPQL转换为以下SQL:
Hibernate:
select
s1_0.idx,
s1_0.idy,
s1_0.idz,
s1_0.description
from
some_entity s1_0
where
(
s1_0.idx,s1_0.idy,s1_0.idz
) in (select
?,?,?
from
dual)
and s1_0.description is not null
型
我想知道为什么Hibernate 6.2将id = :id
转换为子查询,而不是像Hibernate 5那样逐个字段比较复合主键?
我尝试在Sping Boot 2.7.13 / Hibernate 5.6中执行相同的代码,JPQL按预期进行了翻译:
Hibernate:
select
someentity0_.idx as idx1_1_,
someentity0_.idy as idy2_1_,
someentity0_.idz as idz3_1_,
someentity0_.description as description4_1_
from
some_entity someentity0_
where
someentity0_.idx=?
and someentity0_.idy=?
and someentity0_.idz=?
and (
someentity0_.description is not null
)
型
使用AND
和=
单独比较复合PK属性,而不是使用IN
运算符比较的Hibernate 6.2:
...
(
s1_0.idx,s1_0.idy,s1_0.idz
) in (select
?,?,?
from
dual)
...
型
1条答案
按热度按时间djp7away1#
首先,当通过id检索实体时,你很可能不需要使用
@Query
注解的方法,请在这里检查一些想法:JPA Query with several different @Id columns您描述的行为在HBN6中引入,相关代码位于AbstractSqlAstTranslator#visitRelationalPredicate方法中:
字符串
在这种情况下,我认为HBN开发人员不熟悉
Oracle
语法,即上述代码段中的注解Oracle support tuples only for the IN subquery predicate
不正确:标准的Oracle
方法来编写比较元组的表达式如下(注意双括号):型
如果您遇到性能问题,我建议您在HBN Jira中提出一个bug