当前位置: 首页 > 面试题库 >

使用单表继承在实体层次结构上进行JPA标准查询

刘胜泫
2023-03-14
问题内容

说我有以下实体:

@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 = ?;

我不想构建两个单独的查询,因为它们有很多重叠(即,大多数属性都在基类中)。但是,如果我将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
));

现在,我明白了为什么上面的代码示例不起作用,但是我想知道是否有解决方法。


问题答案:

我设法通过使用CriteriaBuilder.treat()将BaseEntity根向下转换为与子类类型相对应的新根来解决此问题,如下所示:

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")
));


 类似资料:
  • 问题内容: 我有两个平行的继承链: 我的经验是,并行继承层次结构在增长时会成为维护上的麻烦。 即不添加方法到我的主要类。 如何避免并行继承层次结构而又不破坏关注点分离的概念? 问题答案: 我正在考虑使用“访客”模式。 这样,您就可以避免多余的继承树,并使格式化逻辑与Vehicle类分开。当然,当您创建新的载具时,您必须向Formatter接口添加另一种方法(并在Formatter接口的所有实现中实

  • 当使用“joined”、“single”或“concrete”表继承样式在继承层次结构中映射类时,如中所述 映射类继承层次结构 通常的行为是,对特定基类的查询也将生成与子类相对应的对象。当单个查询能够返回每个结果行具有不同类或子类的结果时,我们使用术语“多态加载”。 在多态加载领域,特别是联合表继承和单表继承,还有一个额外的问题,子类属性需要预先查询,然后再加载。当预先查询某个特定子类的属性时,我

  • SQLAlchemy支持三种继承形式: 单表继承 ,其中几种类型的类由一个表表示, 具体的表继承 ,其中每种类型的类都由独立的表表示,并且 联接表继承 ,其中类层次结构在依赖表中被分解,每个类都由其自己的表表示,该表只包含该类的本地属性。 最常见的继承形式是单表和联接表,而具体的继承则面临更多的配置挑战。 在继承关系中配置映射器时,SQLAlchemy可以加载元素 polymorphically

  • 到目前为止,我们一直在使用Spring JpaRepository来满足我们的需求。我觉得这个新需求需要自定义查询,我不认为可以直接使用JParepository来处理这个问题。我只想知道你是怎么想的。不需要自定义sql查询就可以做到这一点吗?

  • 问题内容: 我们对PostgreSQL中的继承以及在JPA中将其映射为实体存在疑问。我们的数据库和我们要映射的表是: 我们在Netbeans 7.1.2中使用自动工具将它们映射到实体。起初我认为仅添加就足够了 因此,它只是 扩大了 ,但无法正常工作。最好的方法是什么?提前致谢。 问题答案: JPA的继承概念基于普通表。它并没有真正“理解” PostgreSQL表继承的想法。这是使用旨在暴露功能的最

  • 为了澄清我的问题,让我用一种或多或少相同的方式重新措辞: 为什么Haskell中有超类/类继承的概念?导致这种设计选择的历史原因是什么?例如,为什么有一个没有类层次结构的基库,只有相互独立的类型库是如此糟糕? 此外,我在类继承中看到的一个可能不太好的事情是:我认为一个类实例会默默地选择一个对应的超类实例,这可能是为该类型实现的最自然的实例。让我们把单子看作函子的子类。也许可以有不止一种方法来定义某