【发布时间】:2026-02-02 12:45:01
【问题描述】:
在我的项目中,我有一个 JPA 层次结构 Location -> Site。
@Entity
@Table(name = "LOCATION")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="LOC_TYPE",discriminatorType=DiscriminatorType.STRING)
public class Location {
...
}
@Entity
@DiscriminatorValue("SI")
public class Site extends Location {
...
}
现在,每个Employee 都有一个分配了Location 的列表(即使据我所知,所有这些位置实际上都是Site)。在某些部分,我需要Sites 的列表,Employee 已分配给(注意,我定义的关系是Locations)。
使用 Hibernate 3.2,我可以只编写 Location 的查询并按判别式过滤;返回的类是更具体的子类的实例,v.g.:
Query query = em.createQuery("SELECT loc FROM Location loc WHERE loc.type=\"SI\"");
List<Location> locations = (List<Location>) query.getResultList();
for (Location location : locations) {
Site mySite = (Site) location;
...
}
但是,我找不到任何文档来说明这种行为是由 JPA 规范保证还是仅仅是 Hibernate 的实现决定。在最后一种情况下,我不应该使用这种方法,因为如果我切换供应商,它可能会改变)。
你能告诉我标准是否支持我的方法吗?
顺便说一句,我在 Hibernate 3.2 上使用 JPA 1
更新:
为了澄清我想要什么,这是我实施的“安全警报”。请记住,disc 属性是鉴别器列,因此我确信返回的对象会作为Site 实例持续存在。
Query query = em.createQuery("SELECT lo FROM Employee em JOIN em.location lo WHERE lo.disc = 'SI'");
List<Location> locations = (List<Location>) query.getResultList();
List<Site> site = new ArrayList<Site>();
for (Location location : locations) {
if (location instanceof Site) {
sites.add((Site) location);
} else {
log.warn("Found a Location that is not instance of Site");
}
}
JPA 规范是否指定我的log.warn 语句永远不会被调用? AFAIK,也许一个实现可以返回一堆Location,它们不是Site 的实例。当然,在这种情况下,只有Location 属性可用;这种行为有点像 C++ 中的切片。
【问题讨论】:
-
我认为你仍然没有解释你的问题。您是否有一个映射到
LOC_TYPEDB 列的Java 字段disc?如果没有,那么您可以简单地尝试一下。此外,在您的示例中:为什么不直接查找站点实体:SELECT s FROM Site s WHERE...? -
我的 JPQL 有点过于简单化了,现在它更具代表性。我不能只选择
Site实体,因为我通过导航到Location超类来获取它们。作为最后一个解决方案,我可以使用一个子选择来解决它,该子选择将 ID 从Locations 返回到Sites 的选择,但这个问题让我想知道这个问题(另外,我尽量避免@ 987654345@ 子选择以解决性能问题)。 -
1.子选择比
IN差。 2.IN从来都不是问题,只要你没有 1000 个值。 3. 你没有说我的第一个想法(也许你已经使用了):只需添加一个映射到LOC_TYPEDB 鉴别器列的 JAVA 字段 eType 并在查询中使用它。 -
如果您只要求使用鉴别器列的站点类型的记录,为什么您认为您会获得其他信息。 ?这是一个问题,如果该事件是可能的?
-
@Koitoer 问题是:返回的实例将是
Site类型?我的 JPQL 需要Location,因此它可以像 C++ 对对象进行切片并返回带有行内容的Location实例。显然,Site中定义的属性将不可用(就像切片一样),但我仍然会得到 JPQL 查询的要求。我的问题可以改写为:我可以确定我将获得最初用于存储实体的同一类(或该类的代理)的实例吗?扭曲,我知道,但没有找到阻止它的规范。
标签: jpa