Say I have the following entities:
@Entity
@Inheritance(strategy = SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class BaseEntity {
private Date someDate;
private Date otherDate;
private boolean flag;
}
@Entity
@DiscriminatorValue("entity1")
public class Entity1 extends BaseEntity {
private String someProperty;
}
@Entity
@DiscriminatorValue("entity2")
public class Entity2 extends BaseEntity {
private String otherProperty;
}
I'm trying to build a criteria query that returns instances of BaseEntity based on properties in BaseEntity and both of the subclasses. So essentially I'm looking for a criteria query that corresponds to this pseudo-SQL:
SELECT * FROM <BaseEntity table name>
WHERE someDate < ? AND otherDate > ? AND flag = ?
AND someProperty = ? AND otherProperty = ?;
I'd rather not build two separate queries since they have so much overlap (i.e. most of the properties are in the base class). However, I haven't figured out a way to reference the subclass properties in the query if I declare BaseEntity as the root. Is it possible to build a criteria query like this?
UPDATE:
Maybe some code would clarify the question. I'd essentially like to do something like this:
CriteriaBuilder builder = ...;
CriteriaQuery<BaseEntity> query = ...;
Root<BaseEntity> root = ...;
query.select(root).where(builder.and(
builder.lessThan(root.get(BaseEntity_.someDate), new Date()),
builder.greaterThan(root.get(BaseEntity_.otherDate), new Date()),
builder.isTrue(root.get(BaseEntity_.flag)),
builder.equal(root.get(Entity1_.someProperty), "foo"), <-- This won't work
builder.equal(root.get(Entity2_.otherProperty), "bar") <-- Neither will this
));
Now, I understand why the above code sample doesn't work, but I'd like to know if there's a way to get around it.
I managed to solve this by downcasting the BaseEntity root into new roots that correspond to the subclass types with CriteriaBuilder.treat() like this:
Try
Junction
. You can always do something like this:I hope I got your question Correctly.