Jpa 从层次结构中检索的实体的类
在我的项目中,我有一个JPA层次结构Jpa 从层次结构中检索的实体的类,jpa,Jpa,在我的项目中,我有一个JPA层次结构Location->Site @Entity @Table(name = "LOCATION") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="LOC_TYPE",discriminatorType=DiscriminatorType.STRING) public class Location { ... } @Entity @Discrimi
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 {
...
}
现在,每个员工
都分配了一个位置
列表(即使据我所知,所有这些位置实际上都是站点
)。在某些方面,我需要员工分配给的站点
s的列表(注意,我定义的关系是与位置
s的关系)
使用Hibernate 3.2,我可以只编写位置的查询
,并通过判别式进行过滤;返回的类是更具体的子类的实例,例如:
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规范是否规定永远不会调用我的log.warn
语句?好吧,也许一个实现可以返回一堆不是站点
实例的位置
。当然,在这种情况下,只有位置
属性可用;行为有点像在C++中切片,在 从版本2开始,你有<代码>类型(e)< /C>函数。规范中的示例:
SELECT e FROM Employee e WHERE TYPE(e) IN (Exempt, Contractor)
摘自JPA 2.0规范(4.6.17.4实体类型表达式)):
实体类型表达式可用于限制查询多态性。
TYPE运算符返回参数的确切类型
注意JPA。另一方面,您的示例对基本的JPA机制提出了质疑,我想再次强调:当您从DB中获取一行(使用JPA查询)时,其鉴别器值特定于站点
实体,您可以确定Java对象将是该类的实例(即站点
类)。现在我相信规范不会强制提供者其类为站点
(即fetchedEntity.getClass()==Site.class
),但您可以100%确定站点
的fetchedEntity实例返回true
注意Hibernate。根据我使用Hibernate的经验,我只能添加fetchedEntity.getClass()==Site.class
在Hibernate中返回true(当然,除了fetchedEntity instanceof Site
之外).谢谢你的提示,很高兴知道这个选项。无论如何,WHERE
部分已经包括在内,因为我通过鉴别器进行过滤,我想要的是某种程度上保证检索到的e
实际上已经创建为豁免或承包商
实例(不仅仅是一名普通的员工)你所说的“部分已经涵盖”是什么意思?据我所知,这正是你需要的(如果JPA1.0支持的话):这些员工将完全属于那些Java类型:豁免或承包商,而不是普通的员工。JPA1不支持类型(我刚刚检查了它)。我通过鉴别器进行过滤来解决它(就像在我的JPQL
中一样)。无论如何,我想要的是规范的一部分(或者没有)这确保了您最后的确认;我可能有点太担心了,但我有一种感觉,如果文档没有指定,某些实现可能会返回一个普通的Employee
实体,而不是原始的子类(因为这是JPQL
“所要求的”)好吧,这个示例来自规范(正如我之前所写的)。我已经从规范中添加了有趣的部分。除此之外,我只能建议单独打开规范:)对问题进行了澄清。我认为您仍然没有解释您的问题。您是否有映射到LOC\u TYPE
DB列的Java字段disc
de>?我的JPQL有点过于简单,现在它更具代表性。我不能只选择站点
实体,因为我通过导航到位置
超类来获取它们。作为最后一个解决方案,我可以使用一个子选择来解决它,该子选择将ID从位置
返回到选择的位置但是这个问题让我对这个问题感到疑惑(同时,我尽量避免在
Subselect中使用性能问题的)。1.Subselect比
中的更糟糕。2.
中的从来都不是问题,只要你没有1000个值。3.你没有对我的第一个想法说任何话(也许你已经用过了):只需添加一个映射到locu TYPE
DB discriminator列的JAVA字段eType,并在查询中使用它。如果您只是询问属于使用discriminator列的站点类型的记录,为什么您认为您将获得其他类型的记录。?这是一个是否可能发生该事件的问题?@Koitoer问题是:实例翻转将是“<代码>站点< /代码>类型?我的JPQL要求<代码>位置<代码>,因此它可以像C++的对象切片一样,并返回带有行内容的代码>位置< /Calp>实例。显然,在<代码>站点< /> >中定义的属性将不可用(如切片所示),但我仍然可以得到JPQL查询所要求的。我的问题可以改写为:我是否可以确定我将获得一个与最初用于存储实体的类(或该类的代理)相同的实例?我知道,这是扭曲的,但没有发现阻止它的规范。
SELECT e FROM Employee e WHERE TYPE(e) IN (Exempt, Contractor)