Java Spring——在存在`@Query`注释的情况下,JPA投影由接口方法顺序而不是名称解析?
我的理解是,在SpringJPA中创建投影时,字段将按名称进行解析 使用Java Spring——在存在`@Query`注释的情况下,JPA投影由接口方法顺序而不是名称解析?,java,spring,spring-data-jpa,jpql,projection,Java,Spring,Spring Data Jpa,Jpql,Projection,我的理解是,在SpringJPA中创建投影时,字段将按名称进行解析 使用@Query注释时,情况似乎并非如此 这是预期的行为还是我的查询有问题 假设我有一个实体 @实体 @表(name=“foo”) 公开课Foo{ @身份证 @生成值(策略=标识) 私有整数id; @列(name=“code”) 私有字符串码; @列(name=“name”) 私有字符串名称; …更多我们不感兴趣的。。。 } 我们只想提取id、name和code属性。让我们编写一个简单的投影界面: @Repository pu
@Query
注释时,情况似乎并非如此
这是预期的行为还是我的查询有问题
假设我有一个实体
@实体
@表(name=“foo”)
公开课Foo{
@身份证
@生成值(策略=标识)
私有整数id;
@列(name=“code”)
私有字符串码;
@列(name=“name”)
私有字符串名称;
…更多我们不感兴趣的。。。
}
我们只想提取id
、name
和code
属性。让我们编写一个简单的投影界面:
@Repository
public interface FooRepository extends JpaRepository<Foo, Integer> {
FooTestProjection findOneByCode(String code);
interface FooTestProjection {
Integer getId();
String getName();
String getCode();
}
}
interface FooTestProjection {
Integer getId();
String getCode();
String getName();
}
有效
这里的期望是按名称解析属性。因此,让我们在投影界面中切换getCode()
和getName()
:
@Repository
public interface FooRepository extends JpaRepository<Foo, Integer> {
FooTestProjection findOneByCode(String code);
interface FooTestProjection {
Integer getId();
String getName();
String getCode();
}
}
interface FooTestProjection {
Integer getId();
String getCode();
String getName();
}
是的,仍然有效
现在,假设我们想要对所有的Foo
进行投影,并且我们想要使用@Query
进行投影
(动机:我们最终希望构造一个包含不相关表属性的投影,因此我们使用@Query
来左连接它们。)
因此,让我们调整我们的存储库方法:
@Repository
public interface FooRepository extends JpaRepository<Foo, Integer> {
@Query("SELECT" +
" f.id AS fooId," +
" f.name AS fooName," +
" f.code AS fooCode" +
" FROM Foo f"
)
List<FooTestProjection> findProjections();
interface FooTestProjection {
Integer getFooId();
String getFooName();
String getFooCode();
}
}
有效
测试绿色,一切正常,不是吗
没有
这里,我们的期望是Spring将查看我们构建的结果集,并通过我们定义的列别名将它们与投影接口匹配
事实并非如此
让我们在界面中切换getFooCode()
和getFooName()
,但不要在查询中切换:
这个又起作用了
我发现这与直觉极为相悖,以至于我质疑我的质疑的有效性
如果有人能解释一下这种行为,我们将不胜感激。请您只说明不起作用的情况。这是太多的信息,我想say@pvpkiran当然上面用标记的例子失败了
。我的猜测是,当映射在实体和投影之间时,Spring可以一个字段一个字段地映射,而不会出现问题。但是,当映射在手动查询和投影之间时,由于别名是可选的,并且可以使用增加结果复杂性的联接和函数,因此Spring只选择使用字段排序而不是字段命名进行映射。
@Query("SELECT" +
" f.id AS fooId," +
" f.name AS fooName," +
" f.code AS fooCode" +
" FROM Foo f"
)
List<FooTestProjection> findProjections();
interface FooTestProjection {
Integer getFooId();
String getFooCode();
String getFooName();
}
@Query("SELECT" +
" f.id AS fooId," +
" f.code AS fooCode," +
" f.name AS fooName" +
" FROM Foo f"
)
List<FooTestProjection> findProjections();
interface FooTestProjection {
Integer getFooId();
String getFooCode();
String getFooName();
}