简体   繁体   English

Spring数据jpa,jparepository返回字符串列表代替DTO对象

[英]Spring data jpa, jparepository returning list of string in place of DTO object

I have a interface implementing JPARepository and have three methods, one of them is having a custom @Query . 我有一个实现JPARepositoryinterface ,有三个方法,其中一个是自定义@Query

public interface PersonRepository extends JpaRepository<Person, Long> {

  List<Person> getPersonBycountryCode(String countryCode);

  List<Person> findByCountryCodeAndCity(String string,String city);

  @Query(value = "SELECT person.firstName as firstName, person.lastName as lastName, person.countryCode as country, person.city as city,"
              + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
              + " + POWER((53 * (person.experience - :experience )), 2)) as eligibility"
              + " FROM Person person"
              + " ORDER BY eligibility ASC")
  List<PersonDetailsDto> findPersonDetailsByEligibility(
          @Param("age") BigDecimal age,
          @Param("experience") BigDecimal experience,
          Pageable pageable
  );
}

Problem is: method with @Query does not return list of PersonDetailsDto but return list of list of strings ( List<List<String>> ). 问题是: @Query方法不返回PersonDetailsDto列表但返回字符串List<List<String>>List<List<String>> )。

PersonDetailsDto is a POJO class with all the variables described in a query output (firstName, lastName, country, city, eligibility) and also a constructor with all the variables as Parameters. PersonDetailsDto是一个POJO类,其中包含查询输出中描述的所有变量(firstName,lastName,country,city,eligibility)以及包含所有变量作为Parameters的构造函数。 Other two methods does return list of Person object. 其他两个方法确实返回Person对象的列表。

Any idea? 任何想法?

Actually JpaRepository<Person, Long> means that, you can use only Person as your dto in jpa repository methods. 实际上JpaRepository<Person, Long>意味着,你只能在jpa存储库方法中使用Person作为你的dto。

For your solution you can just define your dto interface inside the repository : 对于您的解决方案,您只需在存储库中定义dto接口:

public interface PersonRepository extends JpaRepository<Person, Long> {

  List<Person> getPersonBycountryCode(String countryCode);

  List<Person> findByCountryCodeAndCity(String string,String city);

  @Query(value = "SELECT person.firstName as firstName, person.lastName as lastName, person.countryCode as country, person.city as city,"
              + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
              + " + POWER((53 * (person.experience - :experience )), 2)) as eligibility"
              + " FROM Person person"
              + " ORDER BY eligibility ASC")
  List<PersonDetailsDto> findPersonDetailsByEligibility(
          @Param("age") BigDecimal age,
          @Param("experience") BigDecimal experience,
          Pageable pageable
  );

 //define the interface here
 public interface PersonDetailsDto{
   public String getFirstName();
   public String getLastName();
   public String getCountry();
   public String getCity();
   public Integer getEligibility();
 }

}

If I am not wrong the idea behind JPA not looking for specific fields is that is cost (efficiency wise) the same to bring one column or all columns from one row of the table.But to solve your problem you can set nativeQuery = true in the @Query annotation from a Repository class like this: 如果我没有错,那么JPA背后的想法就是不寻找特定的字段就是成本(效率明智)相同,从表格的一行带来一列或所有列。但是为了解决你的问题你可以设置nativeQuery = true in来自Repository类的@Query注释,如下所示:

public static final String FIND_SOMETHING = "SELECT somethingId, somethingName FROM something";

@Query(FIND_SOMETHING, nativeQuery = true)
public List<Object[]> findSomethings();

I hope this will help you to resolve your problem. 我希望这可以帮助您解决问题。

You can use new keyword in query of @Query. 您可以在查询@Query时使用new关键字。 And make sure you have the appropriate constructor for PersonDetailsDto and also change package name. 并确保您具有适当的PersonDetailsDto构造函数,并更改包名称。

@Query(value = "SELECT new com.company.PersonDetailsDto(person.firstName, person.lastName, person.countryCode , person.city ,"
          + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
          + " + POWER((53 * (person.experience - :experience )), 2)) "
          + " FROM Person person"
          + " ORDER BY eligibility ASC")
List<PersonDetailsDto> findPersonDetailsByEligibility(
      @Param("age") BigDecimal age,
      @Param("experience") BigDecimal experience,
      Pageable pageable
);

Similar question's answer . 类似的问题的答案

just call it by its alias, it worked for me like that ex : 只是通过它的别名来调用它,它像我那样对我有用:

@Query(value = "SELECT person FROM Person person"
          + " ORDER BY eligibility ASC")
List<PersonDetailsDto> findPersonDetailsByEligibility(
      @Param("age") BigDecimal age,
      @Param("experience") BigDecimal experience,
      Pageable pageable
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM