web-dev-qa-db-ja.com

SqlResultSetMappingとネイティブクエリを使用したJPAデータリポジトリ

私は次の状況に悩まされていました。

私のエンティティは互いに関連していますが、JPQLを使用できませんでした。ネイティブSQLの使用を余儀なくされました。次に、これらの結果をValueObjectにマップします。明確にするために、オブジェクト配列(_List<Object[]>_)のリストを取得したくありません。いくつかの列だけが必要な6つのエンティティがあります。ネイティブクエリからこのようなマッピングを実装する方法の例を教えてもらえますか?

チュートリアル 私が経験したこと。

私のコード:

_@SqlResultSetMapping(
    name = "findAllDataMapping",
    classes = @ConstructorResult(
            targetClass = MyVO.class,
            columns = {
                    @ColumnResult(name = "userFirstName"),
                    @ColumnResult(name = "userLastName"),
                    @ColumnResult(name = "id"),
                    @ColumnResult(name = "packageName")
            }
    )
)

@NamedNativeQuery(name = "findAllDataMapping",
    query = "SELECT " +
            "    u.first_name as userFirstName, " +
            "    u.last_name as userLastName, " +
            "    i.id as id, " +
            "    s.title as packageName, " +
            "FROM " +
            "    invoice as i " +
            "JOIN user as u on i.user_id=u.id " +
            "LEFT JOIN subscription_package as s on i.subscription_package_id=s.id " +
            "where  u.param1=:param1 and i.param2=:param2" +
)

public class MyVO {
    private String userFirstName;
    private String userLastName;
    private Long id;
    private String packageName;

    public MyVO (String userFName, String userLName,
            Long id, String packageName) {
        this.userFirstName = userFName;
        this.userLastName = userLName;
        this.id = id;
        this.packageName = packageName;
    }

    // getters & setters
}
_

私のjpa-repositoryモジュールで:

_public interface MyRepository extends JpaRepository<MyEntity, Long> {
    List<MyVO> findAllOfMyVO(@Param("param1") String param1, @Param("param2") String param2);
}
_

ポイントは、これらの注釈をどこに配置すればよいかわからないので、この種のマッピングを使用できることです。ネイティブクエリでは、new rs.rado.leo.mypackage.MyVO(...)を使用できません。次のエラーが発生しました:

のせいで:

_org.springframework.data.mapping.PropertyReferenceException: No property findAllOfMyVO found for type MyEntity!
_

私の質問は明確だと思います。そうでない場合は、質問を編集できるようにお知らせください。

前もって感謝します!

11
LeoRado

欠落しているresultClassを追加します

@NamedNativeQuery(name = "findAllDataMapping", resultClass = Entity.class, query="sql")

または

@NamedNativeQuery(name = "findAllDataMapping", resultClass = MyVO.class, resultSetMapping ="findAllDataMapping" query = "sql")

最後に、リポジトリ内のクエリを呼び出します

@Query(nativeQuery = true, name = "findAllDataMapping")
List<MyVO> findAllOfMyVO(@Param("param1") String param1, @Param("param2") String param2);
13

クエリをクエリとしてマークする必要があります:)そして、MyEntityの代わりにMyVOを使用する必要があります。

@Repository
public interface MyRepository extends JpaRepository<MyVO, Long> {

    @Query(nativeQuery = true)
    List<MyVO> findAllOfMyVO(@Param("param1") String param1, @Param("param2") String param2);
}
2
Urosh T.

あなたはほとんどそこにいますが、以下の部分については

  1. 全体 @SqlResultSetMappingおよび@NamedNativeQueryは、値オブジェクトではなく、エンティティに存在する必要があります。あなたの場合、それはMyEntityクラスにあり、MyVOクラスにはありません。これで例外が解決するはずです。
  2. それはまだしません。上記を実行した後、以下を変更します

    @NamedNativeQuery(name = "findAllDataMapping"、to
    @ NamedNativeQuery(name = "MyEntity。findAllDataMapping"、

  3. 最後に、場合によっては、@ ColumnResult(name = "userFirstName")の定義で明示的にする必要があります。 ZonedDateTimeやBooleanなどの複雑なフィールドの場合、@ ColumnResult(name = "date_created"、type = ZonedDateTime.class)を明示的に指定する必要がある場合があります。

お役に立てば幸いです。

1
HopeKing