java - JPA:查询对反向一对一关系有限制的实体

标签 java hibernate jpa

我在一个实体上有一个双向的一对一关系。我想查询限制涉及所述关系的反面实体。更具体地说,我想要一对一不映射到任何关系(即为空)的所有实体。

我的实体:

逆:

@Entity
@Table(name="direct_debit")
@Audited
public class DirectDebit implements Serializable{

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

    @OneToOne(mappedBy="debit", targetEntity = Account.class)
    private Account account;

    ...
    Simple getters and setters for all fields here
    ...

}

所有者:

@Entity
@Table(name="account")
@Inheritance(strategy = InheritanceType.JOINED)
@Audited
public abstract class Account implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

    @Column(name = "account_id")
    private String accountId;

    @OneToOne
    @JoinColumn(name="debit_id")
    private DirectDebit debit;

    ...
    Simple getters and setters for all fields here
    ...
}

我的查询是尝试检索所有帐户为空的 DirectDebit 实例。我尝试的条件查询:

@Override
@Transactional
public List<DirectDebit> getUnassignedDirectDebits(){

    EntityManager entityManager = entityManagerProvider.get();

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<DirectDebit> query = criteriaBuilder.createQuery(DirectDebit.class);

    Root<DirectDebit> directDebitRoot = query.from(DirectDebit.class);
    query.select(directDebitRoot);

    query.where(criteriaBuilder.isNull(directDebitRoot.get("account")));

    List<DirectDebit> accounts = entityManager.createQuery(query).getResultList();

    for (DirectDebit account : accounts){
        entityManager.detach(account);
    }

    return accounts;

}

但是,这生成的查询根本不是我所期望的:

select directdebi0_.id as id1_16_ from direct_debit directdebi0_ where directdebi0_.id is null

当然,这个查询不会返回任何结果。

我是否希望 hibernate/jpa 做一些它不能做的事情(因为查询有点奇怪)?有没有其他方法可以实现我在这里想要实现的目标?

我使用 Hibernate 作为 JPA 提供程序,我连接的数据库是 MySQL。

最佳答案

CriteriaBuilder.isNull 仅在所有者的实体中起作用。

根据您的情况,您可以:

@Override
@Transactional
public List<DirectDebit> getUnassignedDirectDebits(){

    EntityManager entityManager = entityManagerProvider.get();

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<DirectDebit> query = criteriaBuilder.createQuery(DirectDebit.class);

    Root<DirectDebit> directDebitRoot = query.from(DirectDebit.class);
    query.select(directDebitRoot);


    //Changes ini
    CriteriaQuery<Integer> ids = criteriaBuilder.createQuery(Integer.class);
    Root<Account> accountRoot = ids.from(Account.class); 
    Path<Integer> path = accountRoot.get("debit").<Integer>get("id");
    TypedQuery<Integer> idsQuery = entityManager.createQuery(ids.select(path));
    query.where(criteriaBuilder.not(directDebitRoot.in(idsQuery.getResultList())));
    //query.where(criteriaBuilder.isNull(directDebitRoot.get("account")));
    //Changes end


    List<DirectDebit> accounts = entityManager.createQuery(query).getResultList();

    for (DirectDebit account : accounts){
        entityManager.detach(account);
    }

    return accounts;
}

关于java - JPA:查询对反向一对一关系有限制的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24800944/

相关文章:

java - Json、JPA、ManytoOne 和 OneToMany => 递归

java - 关闭InputStream是否会关闭与其关联的Channel?

java - 我们可以在 Spring data jpa @Query 中调用或组合 Select 和过程吗

java - 此代码无法检查 NoResultException

java - 如何让程序在循环内获取变量? ( java )

java - 静态内部类的 Hibernate 验证

Java EE 规范与实现

java - Hibernate - 更新/选择后的结果相同

java - CriteriaQuery 加入字符串值

java - 抛出时自定义 Java 异常打印