У меня есть объект, который отображает в виде таблицы, определенной таким образом:Как использовать JPA criteriaBuilder поиск по атрибутам в коллекции суб-атрибутов
@Entity
@Table(name = "cmmn_calendar_evnt")
public class CommonCalendarEvent implements java.io.Serializable
{
private Integer cevId;
private Set<CommonCalendarEventPart> commonCalendarEventParts = new HashSet<CommonCalendarEventPart>(0)
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "CEV_ID", unique = true, nullable = false)
public Integer getCevId()
{
return this.cevId;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "commonCalendarEvent")
public Set<CommonCalendarEventPart> getCommonCalendarEventParts()
{
return this.commonCalendarEventParts;
}
}
и CommonCalendarEventPart определяется следующим образом:
@Entity
@Table(name = "cmmn_calendar_evnt_part")
public class CommonCalendarEventPart implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private Integer ceeId;
private CommonCalendarEvent commonCalendarEvent;
private PartParticipant partParticipant;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "CEE_ID", unique = true, nullable = false)
public Integer getCeeId()
{
return this.ceeId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CEE_CEV_ID", nullable = false)
public CommonCalendarEvent getCommonCalendarEvent()
{
return this.commonCalendarEvent;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CEE_PPT_ID", nullable = false)
public PartParticipant getPartParticipant()
{
return this.partParticipant;
}
}
и, наконец:
@Entity
@Table(name = "part_participant")
public class PartParticipant implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private Integer pptId;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "PPT_ID", unique = true, nullable = false)
public Integer getPptId()
{
return this.pptId;
}
}
Я хочу использовать CriteriaBuilder для создания запроса, находя все CommonCalendarEvent для конкретного идентификатора участника.
В HQL это будет выглядеть примерно так: (хотя я не подтвердил, что это HQL правильно либо)
"from commonCalendarEvent cce where :pptId in (cce.commonCalendarEventParts.partParticipant.pptId)"
Я попробовал несколько подходов, что я думал, были интуитивные попытки в написании criteriaBuilder но мои попытки привели к ошибкам от «неожиданного конца поддерева» до ошибок реализации.
.....
CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<CommonCalendarEvent> criteria = builder.createQuery(CommonCalendarEvent.class);
Root<CommonCalendarEvent> root = criteria.from(CommonCalendarEvent.class);
Fetch<CommonCalendarEvent, CommonCalendarEventPart> evf = root.fetch(CommonCalendarEvent_.commonCalendarEventParts, JoinType.LEFT);
Join<CommonCalendarEvent, CommonCalendarEventPart> evj = (Join<CommonCalendarEvent, CommonCalendarEventPart>) evf;
Join<CommonCalendarEventPart, PartParticipant> evpj = evj.join(CommonCalendarEventPart_.partParticipant);
List<Predicate> pred = new ArrayList<Predicate>();
pred.add(builder.equal(evpj.get(PartParticipant_.pptId), pptId));
criteria.where(builder.and(pred.toArray(new Predicate[] {})));
return getEntityManager().createQuery(criteria).getResultList();
.............
выше дает ошибку «неожиданный конец поддерева».
Любая помощь приветствуется.
Просмотрите представленный код: what is 'evf'? – perissf
Извините скорректированный код. забыли добавить Fetch evf ... его там сейчас. –
Mike
Посмотри мой обновленный ответ – perissf