我有一个实体,它映射到以这种方式定义的表:
@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生成一个查询,查找特定参与者ID的所有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();
.............
上面的产生了一个&#34;意外的子树结束&#34;错误。
感谢任何帮助。
答案 0 :(得分:1)
+1使用延迟初始化。 JPA模型是Object或面向实体的,所以你需要习惯于用这些术语思考。 PartParticipant
未在JPA中由id
标识,而是由对象本身标识。假设你有参与者名单:
PartParticipant pp = em.find(PartParticipant.class, 2);
List<PartParticipant> pps = new ArrayList<PartParticipant>();
pps.add(pp);
然后将该列表传递给查询。在JPQL中:
TypedQuery<CommonCalendarEvent> cev = em.createQuery("select cev from CommonCalendarEvent cev join fetch cev.commonCalendarEventParts cce where cce.partParticipant in :pps", CommonCalendarEvent.class);
List<CommonCalendarEvent> cevs = cev.setParameter("pps", pps).getResultList();
请注意,需要提取以防止LazyInitializationExceptions
。
了解JPQL,CriteriaQuery
应该遵循相同的步骤:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<CommonCalendarEvent> q = cb.createQuery(CommonCalendarEvent.class);
Root<CommonCalendarEvent> r = q.from(CommonCalendarEvent.class);
Join<CommonCalendarEvent, CommonCalendarEventPart> j = r.join("commonCalendarEventParts");
r.fetch("commonCalendarEventParts");
q.select(r).where(j.get("partParticipant").in(pps));
List<CommonCalendarEvent> rs = em.createQuery(q).getResultList();
除了执行fetch之外,您不需要对fetch执行任何特殊操作。如您所见,查询使用PartParticipant Id。
select
commoncale0_.CEV_ID as CEV_ID1_0_0_,
commoncale1_.CEE_ID as CEE_ID1_1_1_,
commoncale1_.CEE_CEV_ID as CEE_CEV_2_1_1_,
commoncale1_.CEE_PPT_ID as CEE_PPT_3_1_1_,
commoncale1_.CEE_CEV_ID as CEE_CEV_2_0_0__,
commoncale1_.CEE_ID as CEE_ID1_1_0__
from cmmn_calendar_evnt commoncale0_
inner join cmmn_calendar_evnt_part commoncale1_ on commoncale0_.CEV_ID=commoncale1_.CEE_CEV_ID
where commoncale1_.CEE_PPT_ID in (?)
答案 1 :(得分:0)
Join<CommonCalendarEvent, CommonCalendarEventPart> evj =
root.join(CommonCalendarEvent_.commonCalendarEventParts);
不是必需的,应该更正第一个连接语句:
coffeescript
查询的其余部分似乎是正确的。