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
Jpa 从层次结构中检索的实体的类_Jpa - Fatal编程技术网

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

在我的项目中,我有一个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 {
  ...
}
现在,每个
员工
都分配了一个
位置
列表(即使据我所知,所有这些位置实际上都是
站点
)。在某些方面,我需要
员工分配给的
站点
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)