如何在Spring数据JPA中的多个查询方法中重用命名查询?

时间:2017-04-20 22:32:16

标签: spring-data-jpa

我想弄清楚如何在Spring Data Jpa中使用@NamedQuery。据我了解,在普通的JPA中,@NamedQuery可以用于代码组织:查询定义一次,可以在任何地方用作常量。

我创建了一个示例来演示问题。我使用的查询非常简单,通常可以用存储库方法名称表示。但它仅仅是例如。

@Entity
@NamedQueries({
    @NamedQuery(name = EXAMPLE_NAMED_QUERY,
                query = "SELECT person FROM Person person WHERE person.id = :personId")
})
public class Person {

    public static final String EXAMPLE_NAMED_QUERY = "Person.exampleNamedQuery";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String propertyOne;

    private String propertyTwo;

    protected Person() {}

    public Person(String name, String propertyOne, String propertyTwo) {
        this.name = name;
        this.propertyOne = propertyOne;
        this.propertyTwo = propertyTwo;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPropertyOne() {
        return propertyOne;
    }

    public void setPropertyOne(String propertyOne) {
        this.propertyOne = propertyOne;
    }

    public String getPropertyTwo() {
        return propertyTwo;
    }

    public void setPropertyTwo(String propertyTwo) {
        this.propertyTwo = propertyTwo;
    }
}

现在我想在我的SpringDataJPA-Repository中使用@NamedQuery

public interface PersonRepository extends JpaRepository<Person, Long> {

    List<PersonProjectionOne> exampleNamedQueryProjectedByOne(@Param("personId") Long personId);

    List<PersonProjectionTwo> exampleNamedQueryProjectedByTwo(@Param("personId") Long personId);

}

但是,我收到此错误:

PropertyReferenceException: No property exampleNamedQueryWithOne found for type Person!

文档说明使用@NamedQuery的存储库方法的名称必须与命名查询定义中的EntityName.XXX完全相同。我希望两次使用相同的@NamedQuery两种方法,这两种方法返回相同的数据但投射方式不同。根据这个答案:https://stackoverflow.com/a/25057982/5728559

  

但是,如果要在多个查询方法上重用查询定义,使用命名查询仍然是一个合理的选择。

我认为这在某种程度上是可能的。怎么样?

1 个答案:

答案 0 :(得分:1)

在查询方法上添加@Query注释,并使用命名查询的名称。 如下所示。

@Query(name = "yourNamedQueryName")
List<PersonProjectionOne> exampleNamedQueryProjectedByOne(@Param("personId") Long personId);

@Query(name = "yourNamedQueryName")
List<PersonProjectionTwo> exampleNamedQueryProjectedByTwo(@Param("personId") Long personId);

在这种情况下,您的命名查询不需要包含实体的名称。