你说,
And what I’m trying to achieve is to query different tables for retrieving both Car and Bus entities.
,但作为第一个考虑,你应该评估你是否真的想这样做.想一想:
>单表继承策略通常是整个层次结构查询的最快速度,例如您想象的执行.它可以使用单个查询执行整个层次结构和具体实体操作,而无需连接或联合.
>单表和联接继承策略确保层次结构中的所有实体都具有不同的键,而不一定是每类表策略的情况.
>单表和连接的继承策略促进了涉及抽象超类的关系;这些并不是每类表策略所支持的.
>支持每类表策略是可选的. JPA提供程序不需要支持它,并且GlassFish引用实现中的默认提供程序实际上不支持它.因此,依赖于每个表的应用程序不能保证是可移植的. (您的提供商,Hibernate,确实支持它.)
你继续说,
However, in this case I get java.sql.SQLSyntaxErrorException:
ORA-00904: "KEY": invalid identifier. Seems like using @Inheritance
together with @AttributeOverride for @Id field doesn’t work.
@AttributeOverride仅指定用于覆盖映射的超类的属性以及嵌入类的字段和属性.如果@Id属性出现在这些上下文中,它确实有效.对于从实体超类继承的持久字段和属性,它没有被指定工作(尽管它都没有被指定为不起作用),但是确实它不能用于具有单表或连接继承策略的这些属性.
如果@AttributeOverride确实适合你,那么这种使用将是不可移植的.另一方面,JPA没有其他任何东西可以实现你想要的.特定的持久性提供程序可以有一个支持它的扩展,但Hibernate历史上并没有这样做 – 从实体超类继承的所有属性都使用相同的名称进行映射.
你也说,
One more thing I’d like to mention is that I’ve tried using
@MappedSuperclass instead of @Inheritance but in this case I’m not
able to query with abstact Vehicle type.
JPA不为您的特定要求组合提供解决方案:
>将每个具体实体类映射到单独的表,
>将ID命名为每个实体表中的不同列名,以及
>支持抽象超类型的多态查询.
如果您不愿意更改其中任何一项,那么您将不得不依赖扩展.在这种情况下,你很幸运:Hibernate支持polymorphic queries,其中多态类型未映射为实体.因此,如果您愿意使您的应用程序明确依赖于Hibernate,那么您可能可以获得您想要的位置.
具体来说,要在Hibernate中执行此操作,您将依赖于“隐式多态”.要做到这一点,你应该避免将超类映射为一个实体,根据你的经验,我猜它也不应该是一个映射的超类.它可以是一个普通的类,虽然它的属性不会持久,或者你可以使用一个接口.如果您的Vehicle类具有要保持持久性的属性,则可以将其更改为可嵌入类.您还需要注释每个车辆实体以指定隐式多态性,例如:
@Entity
@Polymorphism(type = PolymorphismType.IMPLICIT)
// ...
public class Car implements Vehicle {
// ...
}
Hibernate文档声称隐式多态是默认的,但为了清楚起见,我建议无论如何应用@Polymorphism注释.