jpa - 查询DSL/JPQL : how to build a join query?

标签 jpa jpql querydsl

我试图通读 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 是一个简单的实体,带有 id一个pk。
@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 的查询给定特定 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.contact 方向而不是 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);
}

关于jpa - 查询DSL/JPQL : how to build a join query?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23837988/

相关文章:

orm - 如何在 jpql 查询中仅查询父类(super class)实体?

java - jpql错误在哪里附近

hibernate - Solr,Hibernate和QueryDSL与分片

querydsl 3.3.0 - 在带有 N 个 bool 参数的查询中使用 collection.any() 和 elementcollections 生成 N 个 "exists"子查询

java - 将 SQL 解析为 sql builder

android - 从端点类中的实体中选择几个属性

java - 使用 JPA 的 Spring Boot OnetoMany

java - 在不同的事务问题中保持相同的依赖关系

java - JPA的AttributeConverter和Hibernate的ColumnTransformer在属性加解密方面的区别

java - 如何查询 mysql 数据库中的特定实体