Lynx
Lynx

Reputation: 393

How to reuse named query in multiple query methods in Spring data JPA?

I want to figure out how to use @NamedQuery in Spring Data Jpa. As i understand, in plain JPA, @NamedQuery can be used for code organization: query is defined once and can be used anywhere as constant.

I created an example to demonstrate problem. The query i used is very simple and normally can be expressed by repository method name. But it is just for example.

@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;
    }
}

Now i want to use @NamedQuery in my SpringDataJPA-Repository:

public interface PersonRepository extends JpaRepository<Person, Long> {

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

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

}

However, i get this error:

PropertyReferenceException: No property exampleNamedQueryWithOne found for type Person!

The documentation says that repository method that uses @NamedQuery must have name exactly as EntityName.XXX part in named query definition. I want to use the same @NamedQuery twice for two methods that returns same data but differently projected. According to this answer: https://stackoverflow.com/a/25057982/5728559

However, if you want to re-use the query definition on multiple query methods, using a named query is still a reasonable option.

I thought that this is somehow possible. How?

Upvotes: 1

Views: 2965

Answers (1)

Javvano
Javvano

Reputation: 1059

put a @Query annotation on query methods with name of your named query. like shown below.

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

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

and in this case , your named query doesn't need to contain Entity's name.

Upvotes: 3

Related Questions