Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用单表继承对实体层次结构进行JPA条件查询_Java_Jpa_Criteria Api - Fatal编程技术网

Java 使用单表继承对实体层次结构进行JPA条件查询

Java 使用单表继承对实体层次结构进行JPA条件查询,java,jpa,criteria-api,Java,Jpa,Criteria Api,假设我拥有以下实体: @Entity @Inheritance(strategy = SINGLE_TABLE) @DiscriminatorColumn(name = "type") public abstract class BaseEntity { private Date someDate; private Date otherDate; private boolean flag; } @Entity @DiscriminatorValue("entity1"

假设我拥有以下实体:

@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;
}
我正在尝试构建一个条件查询,该查询根据BaseEntity和这两个子类中的属性返回BaseEntity的实例。所以本质上我在寻找一个与这个伪SQL对应的条件查询:

SELECT * FROM <BaseEntity table name>
WHERE someDate < ? AND otherDate > ? AND flag = ?
AND someProperty = ? AND otherProperty = ?;
从中选择*
什么地方?其他日期>?和flag=?
还有someProperty=?和其他属性=?;
我不想构建两个单独的查询,因为它们有太多的重叠(即大多数属性都在基类中)。但是,如果我将BaseEntity声明为根,我还没有找到在查询中引用子类属性的方法。有可能构建这样的条件查询吗

更新:

也许一些代码可以澄清这个问题。我基本上想做这样的事情:

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
));
Criteria crit = session.createCriteria(YourClassName.class);
Criterion cr1 = Restrictions.lt("propertyname", propertyvalue);
Criterion cr2 = Restrictions.gt("propertyname", propertyvalue);
Criterion cr3 = Restrictions.eq("propertyname", propertyvalue);
Criterion cr4 = Restrictions.eq("propertyname", propertyvalue);
Junction cond = Restrictions.conjunction();
cond.add(cr1).add(cr2).add(cr3).add(cr4)
crit.add(cond);
CriteriaBuilder builder = ...;
CriteriaQuery<BaseEntity> query = ...;
Root<BaseEntity> root = ...;
Root<Entity1> entity1 = builder.treat(root, Entity1.class);
Root<Entity2> entity2 = builder.treat(root, Entity2.class);

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(entity1.get(Entity1_.someProperty), "foo"),
        builder.equal(entity2.get(Entity2_.otherProperty), "bar")
));
CriteriaBuilder=。。。;
CriteriaQuery查询=。。。;
根=。。。;
query.select(root).where(builder.and(
builder.lessThan(root.get(BaseEntity\ux.someDate),new Date()),
builder.greaterThan(root.get(BaseEntity_uz.otherDate),new Date()),
builder.isTrue(root.get(BaseEntity.flag)),

builder.equal(root.get(Entity1.someProperty),“foo”),Try
Junction
。您始终可以执行以下操作:

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
));
Criteria crit = session.createCriteria(YourClassName.class);
Criterion cr1 = Restrictions.lt("propertyname", propertyvalue);
Criterion cr2 = Restrictions.gt("propertyname", propertyvalue);
Criterion cr3 = Restrictions.eq("propertyname", propertyvalue);
Criterion cr4 = Restrictions.eq("propertyname", propertyvalue);
Junction cond = Restrictions.conjunction();
cond.add(cr1).add(cr2).add(cr3).add(cr4)
crit.add(cond);
CriteriaBuilder builder = ...;
CriteriaQuery<BaseEntity> query = ...;
Root<BaseEntity> root = ...;
Root<Entity1> entity1 = builder.treat(root, Entity1.class);
Root<Entity2> entity2 = builder.treat(root, Entity2.class);

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(entity1.get(Entity1_.someProperty), "foo"),
        builder.equal(entity2.get(Entity2_.otherProperty), "bar")
));

我希望我正确地理解了您的问题。

我通过将BaseEntity根向下转换为与子类类型对应的新根来解决这个问题,如下所示:

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
));
Criteria crit = session.createCriteria(YourClassName.class);
Criterion cr1 = Restrictions.lt("propertyname", propertyvalue);
Criterion cr2 = Restrictions.gt("propertyname", propertyvalue);
Criterion cr3 = Restrictions.eq("propertyname", propertyvalue);
Criterion cr4 = Restrictions.eq("propertyname", propertyvalue);
Junction cond = Restrictions.conjunction();
cond.add(cr1).add(cr2).add(cr3).add(cr4)
crit.add(cond);
CriteriaBuilder builder = ...;
CriteriaQuery<BaseEntity> query = ...;
Root<BaseEntity> root = ...;
Root<Entity1> entity1 = builder.treat(root, Entity1.class);
Root<Entity2> entity2 = builder.treat(root, Entity2.class);

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(entity1.get(Entity1_.someProperty), "foo"),
        builder.equal(entity2.get(Entity2_.otherProperty), "bar")
));
CriteriaBuilder=。。。;
CriteriaQuery查询=。。。;
根=。。。;
Root entity1=builder.treat(Root,entity1.class);
Root entity2=builder.treat(Root,entity2.class);
query.select(root).where(builder.and(
builder.lessThan(root.get(BaseEntity\ux.someDate),new Date()),
builder.greaterThan(root.get(BaseEntity_uz.otherDate),new Date()),
builder.isTrue(root.get(BaseEntity.flag)),
builder.equal(entity1.get(entity1\uu1.someProperty),“foo”),
builder.equal(entity2.get(entity2\uu2.otherProperty),“bar”)
));

该解决方案完全基于Hibernate,但我正在寻找一个基于JPA标准API的解决方案。此外,我更愿意使用JPA2元模型来引用属性,而不是字符串标识符。op提出的问题是JPA,而不是Hibernate。不工作它会给出null.someDate和null.otherDate,非法错误它现在工作了,我不知道起初是错误的,但它突然开始工作了