Критерии гибернации множественный выбор с соединением - PullRequest
0 голосов
/ 22 февраля 2020

Ниже приведен мой класс сущностей, где я извлекаю эту сущность с помощью построителя критериев, но мне нужно получить только id, title и tags.

Вопрос. java

@Entity
@Table(name = "QUESTION_TITLE")
public class Question {

   @Id
   @Column(name = "id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   @Column(name = "title")
   private String title;

   @OneToOne(mappedBy = "question", cascade = CascadeType.ALL)
   private Body body;

   @ManyToMany
   @JoinTable(name = "QUESTION_TAGS", joinColumns = @JoinColumn(name = "question_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"))
   private Collection<Tags> tags;

   @ManyToOne(targetEntity = Registration.class, fetch = FetchType.LAZY)
   @JoinColumn(nullable = false, name = "user_id", referencedColumnName = "id")
   private Registration registration;
}

ниже - мой код для выборки. Я не знаю, как будет отображаться таблица тегов.

javax.persistence.criteria.CriteriaQuery<Question> query = getCriteriaBuilder().createQuery(Question.class);
Root<Question> question = query.from(Question.class);
query.multiselect(question.get("id"), question.get("title"), question.get("tags"));
List<Question> questionList = entityManager.createQuery(query).getResultList();

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Вы можете использовать запрос критериев кортежа :

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
Root<Question> root = criteria.from(Question.class);
Path<Long> qId = root.get("id");
Path<String> qTitle = root.get("title");
Join<Question, Tag> qTag = root.join("tags", JoinType.INNER);

criteria.multiselect(qId, qTitle, qTag);
List<Tuple> tuples = session.createQuery(criteria).getResultList();
for (Tuple tuple : tuples)
{
   Long id = tuple.get(qId);
   String title = tuple.get(qTitle);
   Tag tag = tuple.get(qTag);
}

Другой альтернативой для выбора нескольких значений является выбор объекта, который будет "оборачивать" несколько значений , Для этого подхода вы должны объявить класс-оболочку:

public class QuestionTag
{
   private final Long id;
   private final String title;
   private final Tag tag;

   public QuestionTag(Long id, String title, Tag tag)
   {
      this.id = id;
      this.title = title;
      this.tag = tag;
   }

   public Long getId()
   {
      return id;
   }

   public String getTitle()
   {
      return title;
   }

   public Tag getTag()
   {
      return tag;
   }
}

, а затем использовать его в запросе:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<QuestionTag> criteria = builder.createQuery(QuestionTag.class);
Root<Question> root = criteria.from(Question.class);
Path<Long> qId = root.get("id");
Path<String> qTitle = root.get("title");
Join<Question, Tag> qTag = root.join("tags", JoinType.INNER);
criteria.select(builder.construct(QuestionTag.class, qId, qTitle, qTag));

List<QuestionTag> wrappers = session.createQuery(criteria).getResultList();
0 голосов
/ 23 февраля 2020

Если вы хотите получить только идентификатор, заголовок и теги объекта Question, вы можете использовать CriteriaQuery with Tuple .

Попробуйте следующий код:

   CriteriaQuery<Tuple> query = getCriteriaBuilder().createTupleQuery();
   Root<Question> question = query.from(Question.class);
   query.multiselect(question.get("id"), question.get("title"), question.get("tags"));
   List<Tuple> questionList = entityManager.createQuery(query).getResultList();
...