javaspring-bootspring-data-jpaprojection

Can a Spring JPA Entity implement a Projection interface?


Interface-based Projections are a handy feature in Spring JPA, allowing a Repository to return different interfaces. For a simple example, this entity...

@Entity
@Table(name = "entity")
@Getter
@Setter
@ToString
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String foo;
    private String bar;
}

...can omit a field and result from a native query.

public interface EntityDTO {
    String getFoo();
    String getBar();
}

@Repository
public interface EntityRepository extends CrudRepository<MyEntity, Integer> {
    @Query(nativeQuery = true, value = "select * from entity where id = :id")
    EntityDTO findDtoById(int id);
}

The above works... unless I want the entity itself to implement the projection interface.

public class MyEntity implements EntityDTO

This relationship seems natural, since the entity does in fact implement the interface, and service methods shouldn't care whether they're reading from an entity or some other projection; but implementing the projection results in an exception from the query.

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [EntityDTO]

Is there a way to make JPA proxy the EntityDTO as an unrelated interface, even when it is implemented by MyEntity?


Solution

  • You can create an interface with the common methods (getFoo(), getBar()) and make both EntityDTO and MyEntity extend/implement it. Then you can use it as a type wherever entity itself (not interested in id) or its projection is provided.