基于接口的投影是Spring JPA中的一个方便的功能,允许存储库返回不同的接口。举个简单的例子,这个实体...
@Entity
@Table(name = "entity")
@Getter
@Setter
@ToString
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String foo;
private String bar;
}
...可以省略本机查询的字段和结果。
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);
}
以上方法有效...除非我希望实体本身实现投影接口。
public class MyEntity implements EntityDTO
这种关系看起来很自然,因为实体实际上确实实现了接口,并且服务方法不应该关心它们是从实体还是其他投影读取;但实施投影会导致查询出现异常。
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [EntityDTO]
有没有办法让 JPA 将
EntityDTO
代理为不相关的接口,即使它是由 MyEntity
实现的?
您可以使用常用方法(
getFoo()
、getBar()
)创建一个接口,并让 EntityDTO
和 MyEntity
扩展/实现它。然后,只要提供实体本身(对id
不感兴趣)或其投影,您就可以将其用作类型。