QueryDSL / JPQL: как построить запрос соединения?
Я попытался прочитать документы QueryDSL, но я все еще очень смущен. Я привык писать много SQL, но это моя первая настоящая трещина в использовании QueryDSL w/ JPQL (JPA2).
у меня есть следующие сущности:
@Entity
public class Provider implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Version
@Column(name = "version")
private Integer version;
private String name;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "provider_contact", joinColumns = @JoinColumn(name = "contact_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "provider_id", referencedColumnName = "id"))
@OrderColumn
private Collection<Contact> contact;
}
где контакт-это простая сущность с id
для ПК.
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
/**
* User first name
*/
@NotNull
private String firstName;
/**
* User last name
*/
@NotNull
private String lastName;
}
Я пытаюсь написать запрос, который возвращает Contact
объект с определенным контактом.id и провайдер.id. Если объект контакта не является частью коллекция контактов поставщика, я ищу значение null.
Я пробовал следующие:
public Contact getContact( long providerId, long contactId ){
Predicate p = QProvider.provider.id.eq(providerId).and(QContact.contact.id.eq(contactId));
JPQLQuery query = new JPAQuery(em);
return query.from(QProvider.provider).innerJoin(QProvider.provider.contact).where(p).singleResult(QContact.contact);
}
но я получаю следующую ошибку:
Caused by: java.lang.IllegalArgumentException: Undeclared path 'contact'. Add this path as a source to the query to be able to reference it.
at com.mysema.query.types.ValidatingVisitor.visit(ValidatingVisitor.java:78)
at com.mysema.query.types.ValidatingVisitor.visit(ValidatingVisitor.java:30)
at com.mysema.query.types.PathImpl.accept(PathImpl.java:94)
Я предполагаю, что это как-то связано с тем, что мой предикат ссылается на QContact.направление контакта, а не часть QProvider.поставщик.контактный объект, но я действительно в недоумении, как это сделать.
Я вообще на правильном пути? Я даже не уверен ... join также является правильным.
1 ответов
Это должно работать
public Contact getContact(long providerId, long contactId) {
QProvider provider = QProvider.provider;
QContact contact = QContact.contact;
return new JPAQuery(em).from(provider)
.innerJoin(provider.contact, contact)
.where(provider.id.eq(providerId), contact.id.eq(contactId))
.singleResult(contact);
}