web-dev-qa-db-ja.com

Projectionを使用したSpring JPAネイティブクエリで「ConverterNotFoundException」が発生する

Spring JPAを使用していますが、ネイティブクエリが必要です。このクエリでは、テーブルから2つのフィールドのみを取得する必要があるため、 Projections を使用しようとしています。それは動作していません、これは私が得ているエラーです:

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.IdsOnly]

リンクしたページの指示に正確に従おうとしましたが、クエリを非ネイティブにしようとしました(投影を使用する場合、実際にはネイティブにする必要がありますか?)が、常にそのエラーが発生します。
インターフェイスを使用すると機能しますが、結果はプロキシであり、jsonに変換できる「通常の結果」である必要があります。

だから、ここに私のコードがあります。エンティティ:

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@Entity
@Table(name = "TestTable")
public class TestTable {

    @Id
    @Basic(optional = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "Id")
    private Integer id;
    @Column(name = "OtherId")
    private String otherId;
    @Column(name = "CreationDate")
    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate;
    @Column(name = "Type")
    private Integer type;
}

投影のクラス:

import lombok.Value;

@Value // This annotation fills in the "hashCode" and "equals" methods, plus the all-arguments constructor
public class IdsOnly {

    private final Integer id;
    private final String otherId;
}

リポジトリ:

public interface TestTableRepository extends JpaRepository<TestTable, Integer> {

    @Query(value = "select Id, OtherId from TestTable where CreationDate > ?1 and Type in (?2)", nativeQuery = true)
    public Collection<IdsOnly> findEntriesAfterDate(Date creationDate, List<Integer> types);
}

そして、データを取得しようとするコード:

@Autowired
TestTableRepository ttRepo;
...
    Date theDate = ...
    List<Integer> theListOfTypes = ...
    ...
    Collection<IdsOnly> results = ttRepo.findEntriesAfterDate(theDate, theListOfTypes);  

助けてくれてありがとう。私は自分が間違っていることを本当に理解していません。

10
nonzaprej

クエリは constructor expression を使用する必要があります。

@Query("select new com.example.IdsOnly(t.id, t.otherId) from TestTable t where t.creationDate > ?1 and t.type in (?2)")

そして、Lombokについては知りませんが、2つのIDをパラメーターとして受け取るコンストラクターがあることを確認してください。

10
Robert Niestroj

春のデータを使用すると、仲介者をカットし、単純に定義することができます

public interface IdsOnly {
  Integer getId();
  String getOtherId();
}

次のようなネイティブクエリを使用します。

@Query(value = "Id, OtherId from TestTable where CreationDate > ?1 and Type in (?2)", nativeQuery = true)
    public Collection<IdsOnly> findEntriesAfterDate(Date creationDate, List<Integer> types);

チェックアウト https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

9
shahaf

JPA 2.1では、興味深い ConstructorResult 機能を導入しますnative

4

リポジトリクラスのネイティブクエリメソッドの戻り値の型として、オブジェクト配列のリスト(リスト)を返すことができます。

@Query(
            value = "SELECT [type],sum([cost]),[currency] FROM [CostDetails] " +
                    "where product_id = ? group by [type],[currency] ",
            nativeQuery = true
    )
    public List<Object[]> getCostDetailsByProduct(Long productId);
for(Object[] obj : objectList){
     String type = (String) obj[0];
     Double cost = (Double) obj[1];
     String currency = (String) obj[2];
     }
1
Madhura

2つのテーブルから値をマッピングし、リポジトリファイルでこのように解決する必要があります

@Query("select distinct emp.user.id as id, " +
    "concat(emp.user.firstName, ' ',emp.user.lastName, ' ',emp.extensionNumber) as name from NmsEmployee emp " +
    " where emp.domain.id = :domainId and (emp.activeUntil= null or emp.activeUntil > :lLogin) ")
    List<Selectable> getSelcByDomainId( @Param("domainId") Long domainId, @Param("lLogin") ZonedDateTime lLogin);

選択可能な場所

public interface Selectable {
     Long getId();
     String getName();
}
0
Inês Gomes