私は2つのテーブルを持っています。JPA Criteria Join OneToManyテーブルwhere節が機能しません
CREATE TABLE public.question
(
id SERIAL PRIMARY KEY
, day VARCHAR(2) NOT NULL
, month VARCHAR(2) NOT NULL
, year VARCHAR(4) NOT NULL
);
CREATE TABLE public.question_translation
(
id SERIAL PRIMARY KEY
, question_id INT REFERENCES public.question(id) NOT NULL
, question_text TEXT NOT NULL
, language VARCHAR(2) NOT NULL
);
ここで質問を取得する基準を作成します。このようなSQL:
public static volatile ListAttribute<Question, QuestionTranslation> questionTranslation;
しかし:メタモデルQuestion_.class
に私はこの行を得たので
@Override
public Collection<Question> findByMonthYear(String month, String year, String locale) {
EntityManager em = sessionFactory.createEntityManager();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Question> criteriaQuery = builder.createQuery(Question.class);
List<Predicate> predicates = new ArrayList<>();
Root<Question> questionRoot = criteriaQuery.from(Question.class);
ListJoin<Question, QuestionTranslation> questionTranslationJoinRoot = questionRoot.join(Question_.questionTranslation, JoinType.LEFT);
predicates.add(builder.equal(questionRoot.get(Question_.month), month));
predicates.add(builder.equal(questionRoot.get(Question_.year), year));
predicates.add(builder.equal(questionTranslationJoinRoot.get(QuestionTranslation_.language), locale));
criteriaQuery.select(questionRoot).where(predicates.toArray(new Predicate[]{}));
TypedQuery<Question> query = em.createQuery(criteriaQuery);
String queryString = query.unwrap(Query.class).getQueryString();
return query.getResultList();
}
私はListJoinを使用:JPAのcriteriasそれはこのようになりますを使用してJavaで
SELECT * FROM question q LEFT JOIN question_translation qt ON q.id = qt.question_id WHERE qt.language = 'en'
これは私に返されます。質問欄には質問欄があり、言語欄がen
との2つの項目があります値。しかし、where句を指定すると、言語がen
という値の1つのエントリだけが返されます。私のコードに何が問題なのですか?
更新日#1:
私には2番目のケースがあります。
つ以上のテーブル:
CREATE TABLE public.user_answer
(
uuid VARCHAR(36) PRIMARY KEY
, user_uuid VARCHAR(36) REFERENCES public.users(uuid) NOT NULL
, question_id INT REFERENCES public.question(id) NOT NULL
, answer TEXT NOT NULL
);
そして、私はこのようなSQLを作りたい:
@Override
public UserAnswer findByDayMonthYear(String day, String month, String year, User user, String locale) {
EntityManager em = sessionFactory.createEntityManager();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<UserAnswer> criteriaQuery = builder.createQuery(UserAnswer.class);
List<Predicate> predicates = new ArrayList<>();
Root<UserAnswer> userAnswerRoot = criteriaQuery.from(UserAnswer.class);
Join<UserAnswer, Question> questionJoin = userAnswerRoot.join(UserAnswer_.question);
ListJoin<Question, QuestionTranslation> questionTranslatJoin = questionJoin.join(Question_.questionTranslation);
predicates.add(builder.equal(builder.treat(questionJoin, Question.class).get(Question_.day), day));
predicates.add(builder.equal(builder.treat(questionJoin, Question.class).get(Question_.month), month));
predicates.add(builder.equal(builder.treat(questionJoin, Question.class).get(Question_.year), year));
predicates.add(builder.equal(builder.treat(questionTranslatJoin, QuestionTranslation.class).get(QuestionTranslation_.language), locale));
predicates.add(builder.equal(userAnswerRoot.get(UserAnswer_.user), user));
criteriaQuery.select(userAnswerRoot).where(predicates.toArray(new Predicate[]{}));
TypedQuery<UserAnswer> query = em.createQuery(criteriaQuery);
String queryString = query.unwrap(Query.class).getQueryString();
return query.getSingleResult();
}
:Javaで
SELECT * FROM user_answer ua LEFT JOIN question q on ua.question_id = q.id LEFT JOIN question_translation qt ON q.id = qt.question_id WHERE qt.language = 'en' AND ua.user_uuid = '00000000-user-0000-0000-000000000001' AND q.month = '01' AND q.day = '01' AND q.year = '2016';
JPAのcriteriasを使用して、それはこのようになりますこの場合、質問には、2つのQuestionTranlsationとlanguag es en
とde
ですが、言語がen
のQuestionTranlsationエントリが1つだけ必要です。
この場合、どうすればよいですか?これは、JPA 2.1の機能で可能です
は
は私の質問を更新してください見てください参照してください。 – dikkini
なぜそれが必要ですか?翻訳からの質問にアクセスできます。 –
JPA 2.1を使用して、「JOIN ON language」の使い方を教えてください。 – dikkini