![](/img/trans.png)
[英]Spring Data JPA native query does not follow naming convention with projections
[英]spring data jpa - class based projections with custom query
我需要一個用於自定義查詢的 spring 數據存儲庫方法,並希望使用基於類的投影。
看着這個https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
@Entity
public class Person {
@Id
private Long id;
private String firstName;
private String lastName;
private int age;
}
@Value // lombok annotation to create constructor, equals and hash-code
public class PersonDTO {
private String firstName;
private String lastName;
}
public interface PersonRepository extends Repository<Person, Long> {
List<PersonProjection> findDistinct();
@Query("select distinct firstName, lastName from Person")
List<PersonProjection> findDistinctQuery();
@Query(value = "select distinct first_name, last_name from person", nativeQuery = true)
List<PersonProjection> findDistinctNativeQuery();
}
沒有找到能夠從類型 [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] 轉換為類型 [com.x.PersonDTO] 的轉換器
是否有任何選項可以使其與類(而不是接口)一起使用?
請親自編寫您的方法,如下所示
@Query(value = "select distinct new xxx.xxx.dto.PersonDTO(p.first_name, p.last_name) from person p")
List<PersonProjection> findDistinctNativeQuery();
“xxx.xxx.dto.PersonDTO”這應該指向您的完全限定類名。
供您參考,請查看此https://www.bytestree.com/spring/spring-data-jpa-projections-5-ways-return-custom-object/
我不確定是否有適用於本機查詢的 Spring Data 解決方案,但您可以使用 JPA ConstructorResult :
@Entity
@NamedNativeQuery(
name="Person.findDistinctNativeQuery",
query="select distinct first_name as firstName, last_name as lastName from person",
resultSetMapping="PersonMapping"
)
@SqlResultSetMapping(name="PersonMapping",
classes={
@ConstructorResult(targetClass=PersonDTO.class, columns={
@ColumnResult(name="firstName", type=String.class),
@ColumnResult(name="lastName", type=String.class)
})
})
public class Person {
@Id
private Long id;
private String firstName;
private String lastName;
private int age;
}
@Value // lombok annotation to create constructor, equals and hash-code
public class PersonDTO {
private String firstName;
private String lastName;
}
public interface PersonRepository extends Repository<Person, Long> {
List<PersonProjection> findDistinct();
@Query("select distinct firstName, lastName from Person")
List<PersonProjection> findDistinctQuery();
@Query(name = "Person.findDistinctNativeQuery", nativeQuery = true)
List<PersonDTO> findDistinctNativeQuery();
}
或者您可以從 findDistinctNativeQuery() 返回 Object[],然后手動創建 PersonDTO。
使用 HQL,您也可以使用基於類的投影,唯一的條件 PersonDTO 必須具有所有參數構造函數,其參數名稱必須與根實體類的屬性匹配:
public interface PersonRepository extends Repository<Person, Long> {
...
List<PersonDTO> findDistinct();
}
如果 PersonDTO 屬性與基本實體屬性不匹配,則可以使用HQL 動態實例化。 同樣,這不適用於本機查詢:
public interface PersonRepository extends Repository<Person, Long> {
...
@Query("select new com.x.PersonDTO(firstName, lastName) from Person")
List<PersonDTO> findDistinct();
}
這也有效:
public interface PersonRepository extends CrudRepository<Person, Long> {
@Query(nativeQuery = true,
value = "SELECT DISTINCT fist_name AS firstName, last_name AS lastName FROM person ")
List<PersonNameOnly> findDistinctNames();
interface PersonNameOnly {
String getFirstName;
String getLastName;
}
}
這可以通過FluentJPA完成:
default List<PersonDTO> findDistinctQuery() {
FluentQuery query = FluentJPA.SQL((Person p) -> {
SELECT(DISTINCT(p.getFirstName(), p.getLastName()));
FROM(p);
});
return query.createQuery(getEntityManager(), PersonDTO.class).getResultList();
}
請注意,您必須使用@Data
而不是@Value
注釋@Value
。 有關JPA 存儲庫集成的更多詳細信息。
您需要添加具有與根實體相同的字段名稱的構造函數。 所以你的 DTO 將是,
public class PersonDTO {
private String firstName;
private String lastName;
// constructor , getters setters, equals(…) and hashCode() implementations
}
您可以使用 Lombok 的@Value
注釋來簡化 DTO,
@Value
class PersonDTO {
String firstname, lastname;
}
在此處查看更多詳細信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.