Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA条件连接OneToMany表where子句不起作用_Java_Spring_Hibernate_Jpa 2.0 - Fatal编程技术网

Java JPA条件连接OneToMany表where子句不起作用

Java JPA条件连接OneToMany表where子句不起作用,java,spring,hibernate,jpa-2.0,Java,Spring,Hibernate,Jpa 2.0,我有两张桌子 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 SERIA

我有两张桌子

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如下所示:

@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();
}
@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();
}
选择*从问题q左连接问题翻译qt ON q.id=qt.question\u id其中qt.language='en'

在使用JPA标准的java中,如下所示:

@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();
}
@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();
}
但这一个返回我的问题类,带有列表问题翻译,有两个条目,其中语言字段等于en和de值。但我指定where子句只返回一个语言等于en值的条目。我的代码怎么了

更新1:

我有第二个病例

还有一张表:

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 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();
}
@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();
}
选择*FROM user\u answer ua LEFT JOIN question q on ua.question\u id=q.id LEFT JOIN question\u translation qt on q.id=qt.question\u id,其中qt.language='en'和ua.user\u uuid='00000000-user-0000-000000000001',q.month='01',q.day='01',q.year='2016'

在使用JPA标准的java中,如下所示:

@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();
}
@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();
}
在本例中,问题列表中有两个语言为en和de的问题转换项,但我只需要一个语言为en的问题转换项


在这种情况下我必须做什么?

这在JPA 2.1功能连接上是可能的


请参见

为什么我需要它?你们可以从翻译中获取问题。我使用JPA2.1,给我一个如何使用“加入语言”的建议?