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

,其中Contact是一个简单实体,具有一个pk的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和Provider.id。如果Contact对象不是Provider的Contact集合的一部分,我将查找空值。

我试过以下方法:

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.provider.contact对象的一部分,但我真的很困惑,因为我不知道应该如何做到这一点。

我的思路对吗?我甚至不确定我的连接是否正确。

应该可以了

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

最新更新