어떻게 쿼리 JPA 기준을 사용하여 EmbeddedId의 필드를 기반으로합니까?

롤랜드 로버츠 :

나는 주로 내가 그림부터 검색하여,이 밖으로 내려고 시간의 지난 몇 동안 한 사람이 이미 완료했습니다,하지만 난 대답을 찾는 게 아니에요 나를 위해 작동하는지.

여기에 내가 공공 장소에서 넣을 수 있습니다 뭔가 내 코드의 즉석 번역입니다.

@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쿼리에서. 나는 기쁨, 사람들을 시도하지했습니다. 나는이에 totaly 다른 무언가가 필요하면 내가 어떻게 쿼리의 키 필드를 지정하는 방법 아무 생각이 없다, 또는. 정말 단서가 필요합니다 ...

나는 봄 4.3.8.RELEASE 및 최대 절전 모드 4.3.11.Final, 자바 (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문. 당신은 코드 A를 사용하여 짧은 비트 수

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

추천

출처http://43.154.161.224:23101/article/api/json?id=18884&siteId=1