我在一个实体上有一个双向的一对一关系。我想查询限制涉及所述关系的反面实体。更具体地说,我想要一对一不映射到任何关系(即为空)的所有实体。
我的实体:
逆:
@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/