I got three entities:
public class BaseEntity {
@Id
protected BigInteger id;
@Column(...)
protected int value;
@Column(...)
protected String name;
}
public class ChildOne{
@Id
protected BigInteger id;
@Column(...)
protected String oneName;
@OneToOne
@JoinColumn(name = "R_BaseEntity", nullable = false)
protected BaseEntity baseEntity;
}
public class ChildTwo{
@Id
protected BigInteger id;
@Column(...)
protected String twoName;
@OneToOne
@JoinColumn(name = "R_BaseEntity", nullable = false)
protected BaseEntity baseEntity;
}
What I finally want is a list of BaseEntity
that are not already associated with ChildOne
or ChildTwo
. What I do:
public List<BaseEntity> get List(){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ChildTwo> twoQuery = cb.createQuery(ChildTwo.class);
Root<ChildTwo> twoRoot = twoQuery.from(ChildTwo.class);
Join<ChildTwo, BaseEntity> twoJoin = twoRoot.join(ChildTwo_.baseEntity, JoinType.INNER);
twoQuery.select(twoRoot);
TypedQuery<ChildTwo> query = em.createQuery(twoQuery);
List<BigInteger> baseList = new ArrayList<>();
for (ChildTwo childTwo : query.getResultList()) {
baseList.add(childTwo.getBaseEntity().getId());
}
CriteriaQuery<ChildOne> oneQuery=cb.createQuery(ChildOne.class);
Root<ChildOne> oneRoot=oneQuery.from(ChildOne.class);
Join<ChildOne, BaseEntity> oneJoin = oneRoot.join(ChildOne_.baseEntity,JoinType.INNER);
oneQuery.select(oneRoot);
TypedQuery<ChildOne> query1= em.createQuery(oneQuery);
for(ChildOne childOne:query1.getResultList()){
baseList.add(childOne.getBaseEntity().getId());
}
CriteriaQuery<BaseEntity> baseQuery=cb.createQuery(BaseEntity.class);
Root<BaseEntity> baseRoot=baseQuery.from(BaseEntity.class);
Predicate predicate = baseRoot.get(BaseEntity_.id).in(baseList);
baseQuery.select(baseRoot).where(cb.not(predicate));
return em.createQuery(baseQuery).getResultList();
}
but this is just a disgusting workaround because I can’t achive two things:
- Get just the
BaseEntity
out of the join - transform the two joins into subqueries and do a “not in”
Any help is highly appreciated.