(以下不是我的实际实体,但结构类似)
我目前正在尝试编写一个控制器方法,该方法返回给定提供者的收件人页面。
Provider类看起来像这样:
@Entity
@Table(name="Provider")
public class Provider {
@Id @GeneratedValue
public Long id;
@Column(name="joinDate")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime joinDate;
@ElementCollection(fetch=FetchType.LAZY)
@OneToMany
@JoinTable(
name="Provider_Recipients",
joinColumns=@JoinColumn(name="providerId"),
inverseJoinColumns=@JoinColumn(name="recipientId"))
public Collection<Recipient> recipients;
public Provider() {
}
}
收件人类看起来像这样:
@Entity
@Table(name="Recipients")
public class Recipient {
@Id @GeneratedValue
public Long id;
@ElementCollection(fetch=FetchType.EAGER)
@MapKeyColumn(name="type")
@Column(name="value")
@CollectionTable(
name="Recipient_ProtoAttrs",
joinColumns = @JoinColumn(name="recipientId"))
public Map<String, String> attributes;
public Long quantity;
@Column(name="date")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime date;
public Recipient() {
this.attributes = new HashMap<>();
}
public Recipient(Recipient old) {
this.attributes = new HashMap<>(old.attributes);
this.quantity = old.quantity;
this.date = old.date;
}
}
我正在使用Provider表和Recipients表之间的映射表。
Repository的findAll方法:
@Override
public Page<T> findAll(Predicate predicate, Pageable pageable) {
JPQLQuery countQuery = createQuery(predicate);
JPQLQuery query = querydsl.applyPagination(pageable, createQuery(predicate));
Long total = countQuery.count();
List<T> content = total > pageable.getOffset() ? query.list(path) : Collections.<T> emptyList();
return new PageImpl<>(content, pageable, total);
}
现在问题。尝试以下查询时:
QProvider qProvider = QProvider.provider;
QRecipient qRecipient = QRecipient.recipient;
BooleanExpression exp = qRecipient.in(qProvider.recipients).and(qProvider.id.eq(providerId));
return providerRepo.findAll(exp, new PageRequest(pageNum, PAGE_SIZE));
我得到了
Undeclared path 'provider'. Add this path as a source to the query to be able to reference it.
如果我改为尝试:
QProvider qProvider = QProvider.provider;
QRecipient qRecipient = QRecipient.recipient;
BooleanExpression exp = qRecipient.in((CollectionExpression) new JPASubQuery()
.from(qProvider)
.where(qProvider.id.eq(providerId))
.list(qProvider.recipients));
return providerRepo.findAll(exp, new PageRequest(pageNum, PAGE_SIZE));
然后我得到一个SQL语法错误。具体来说,生成的子查询是
select . from Provider provider1_, Provider_Recipients recipients2_, Recipient recipient3_ where provider1_.id=recipients2_.providerId and recipient2_.recipientId=recipient3_.id and provider1_.id=?
我尝试了几种不同的方法来指定查询和子查询,但我总是得到这两个错误中的一个。
有什么建议吗?
答案 0 :(得分:0)
找到解决方案。
找到一个解决方法(或者更确切地说,我应该首先采用这种方式):
而不是:
BooleanExpression exp = qRecipient.in((CollectionExpression) new JPASubQuery()
.from(qProvider)
.where(qProvider.id.eq(providerId))
.list(qProvider.recipients));
这样:
BooleanExpression exp = qRecipient.id.in(new JPASubQuery()
.from(qProvider).rightJoin(qProvider.recipients, qRecipient)
.where(qProvider.id.eq(providerId))
.list(qRecipient.id));
按预期工作。