Class based projections using a DTO in Spring Data Jpa is not working

Viewed 662

In my Spring Boot application, I am trying to implement a class based projection using DTOs as described at:

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.dtos

I have a domain class that looks like:

@Entity
@Table(name="metadatavalue")
public class MetadataValue {

    @Id
    @Column(name="metadata_value_id")
    private Integer metadataValueId;

    @Column(name="resource_id", insertable=false, updatable=false)
    private Integer resourceId;

    @Column(name="metadata_field_id", insertable=false, updatable=false)
    private Integer metadataFieldId;

    @Column(name="text_value")
    private String textValue;

more class members, getters and setters, etc follow.

I also have a simple DTO class with one member:

public class MetadataDTO {

    private String textValue;

    public MetadataDTO(String textValue) {
        this.textValue = textValue;
    }

    public String getTextValue() {
        return textValue;
    }
}

My repository class is:

public interface MetadataValueRepository extends CrudRepository<MetadataValue, Integer> {

    @Query("SELECT m from MetadataValue m WHERE m.handle.handle = :handle AND m.resourceTypeId=m.handle.resourceTypeId")
    List<MetadataValue> findAllByHandle(@Param("handle") String handle);


    @Query("SELECT new path.to.my.package.domain.MetadataDTO(m.textValue AS textValue) FROM MetadataValue m "
            + "WHERE m.handle.handle = :handle AND m.resourceTypeId=m.handle.resourceTypeId")
    List<MetadataDTO> findAllByHandleDTO(@Param("handle") String handle);
}

The first method, findAllByHandle works as expected, but when running the second method, findAllByHandleDTO, which I had hoped to return the projection, my application throws the error:

java.lang.IllegalArgumentException: Couldn't find PersistentEntity for type class path.to.my.package.domain.MetadataDTO!

I have also tried extending from JpaRepository with the same result. In another attempt, I tried using an Interface based projection which resulted in an almost identical stacktrace, with an internal class substituted for my class.

My project is spring-boot 2.3.0 with Spring Web, Spring Data JPA, Rest Repositories, and PostgreSQL Driver.

Can anybody help me understand what I am doing wrong and set me in the right direction?

Thanks so much!

Update on this question: (I have added the tag spring-data-rest). Experimenting, I have learned that I can successfully call my method, for instance, in the run() method of my application class. It's only when I call the method as a rest endpoint that I see the error. Is this simply an issue of incompatibility with Spring Data Rest?

0 Answers
Related