どのように私は、クエリJPAの基準を使用してEmbeddedIdのフィールドに基づいていますか?

ローランド・ロバーツ:

私は主にIフィギュアので、検索することで、このアウトを理解しようと時間の最後のカップルを費やしてきた誰かがすでにそれを行っているが、私は私の作品の答えを見つけていませんよ。

ここで私は公共の場で置くことができる何かに私のコードのオンザフライ翻訳です。

@Entity @Table(name="result")
public class Result implements Serializable {
    @Embeddable
    public static class ResultPK implements Serializable {
        @Column(name="result_date", nullable=false)
        @Type(type="com.example.HibernateUTC$LocalDateType") // <- UserType
        public LocalDate resultDate;
        @Column(name="name", nullable=false)
        public String name;
        @Column(name="category", nullable=false)
        public String category;
        public ResultPK() {}
        public ResultPK(Date resultDate, String name, String category) {
            this.resultDate = resultDate;
            this.name = name;
            this.category = category;
        }
        // ...more code for hashCode/equals, no setters or getters...
    }

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name="resultDate", column=@Column(name="result_date", nullable = false)),
            @AttributeOverride(name="name", column=@Column(name="name", nullable=false)),
            @AttributeOverride(name="category", column=@Column(name="category", nullable = false)),
            })
    private ResultPK resultId;
    @Column(name="r_square")
    private Double rSq;
    @Column(name="p_value")
    private pValue;

    // ... more code for other fields, setters, getters, but nothing else; vanilla pojo...
}

私は、クエリが隠れているDAOを持っています。私が呼んでいる方法がこれです

@Repository("resultDAO")
public class ResultDAOImpl extends AbstractBaseDAO<Result> implements ResultDAO {
    // boilerplate for intializing base class and other queries
    @Override
    public List<Result> findDateRange(String category, String name, LocalDate begDate, LocalDate endDate) {
        EntityManager em = entityManagerFactory.createEntityManager();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Result> q = cb.createQuery(Result.class);
        Root<Result> root = q.from(Result.class);
        Predicate catMatch = cb.equal(root.get("resultId.category"), category);
        Predicate nameMatch = cb.equal(root.get("resultId.name"), name);
        Predicate dateRange = cb.between(root.get("resultId.resultDate"), begDate, endDate);
        q.select(root).where(cb.and(catMatch, nameMatch, dateRange));
        return em.createQuery(q).getResultList();
    }
}

私は、コードを実行しようとしたときに実行されるクエリは、私はエラーで終わるということ

Exception in thread "main" java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [resultId.category] on this ManagedType [com.example.Result]

私が見つけた同様の質問のいくつかは、私が使用するために必要なように、それは見せていたresultPKか、ResultPKクエリで。私はそれらの、ない喜びを試みました。私は、クエリのキーでフィールドを指定する方法が分からない、または私はこれまでば完全に別の何かを必要とする場合。私は本当に手掛かりを必要とします...

私は春4.3.8.RELEASEや休止状態4.3.11.Final、Javaの8(LOCALDATEを処理するので、のUserType)を使用しています。

実際のコードの私の転写にいくつかの矛盾を修正するために編集されました。

アレックスvaluiskyi:

あなたの述語この方法を変更する必要があります。

 Predicate catMatch = cb.equal(root.get("resultId").get("category"), category);
 Predicate nameMatch = cb.equal(root.get("resultId").get("name"), name);
 Predicate dateRange = cb.between(root.get("resultId").get("resultDate"), begDate, endDate);

使用する必要はありませんちなみにcb.and内部のwhere声明を。あなたは使用してコードを少し短くすることができます

q.select(root).where(catMatch, nameMatch, dateRange);

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=18885&siteId=1