2015-10-12 1 views
0

(Ниже не мои реальные сущности, но они аналогичны по структуре)Необъявленный путь «поставщик»/ошибка синтаксиса SQL с QueryDSL и Hibernate

В настоящее время я пытаюсь написать метод контроллера, который возвращает страницу из получателей данного провайдера.

Средний класс выглядит так:

@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", 
      [email protected](name="providerId"), 
      [email protected](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 таблицей и таблицей получателей. Метод 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

Решение найдено.

Нашли работу вокруг (или, скорее, вероятно, как я должен был сделать это в первую очередь):

Вместо:

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)); 

работы как предполагалось.