Sta*_*yuk 7 java hibernate jpa table-per-class spring-data-jpa
我有以下映射:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue
Long id;
}
@Entity
@Table(name = "car")
@AttributeOverride(name = "id", column = @Column(name = "car_id"))
public class Car extends Vehicle {
}
@Entity
@Table(name = "bus")
@AttributeOverride(name = "id", column = @Column(name = "bus_id"))
public class Bus extends Vehicle {
}
Run Code Online (Sandbox Code Playgroud)
而我想要实现的是查询不同的表以检索两者Car和Bus实体.为此,我创建了以下Spring Data存储库
public interface VehicleRepository extends CrudRepository<Vehicle, Long> {
}
Run Code Online (Sandbox Code Playgroud)
并试着像这样使用它: vehicleRepository.findAll();
但是,在这种情况下,我得到了java.sql.SQLSyntaxErrorException: ORA-00904: "KEY": invalid identifier.好像使用@Inheritance连同@AttributeOverride用于@Id现场不起作用.
我想指出的是,如果Car和Bus实体具有相同的映射,@Id它将完美地工作(但事实并非如此:"car_id"和"bus_id")
此外,我试图将@Id字段从Vehicle类移动到子类,但事实证明每个@Entity应该包含一个@Id.
还有一件事我想提一下,我尝试使用@MappedSuperclass而不是@Inheritance在这种情况下,我无法查询abstact Vehicle类型.
有人可以帮我吗?
谢谢
你说,
我想要实现的是查询不同的表以检索 Car 和 Bus 实体。
,但作为首要考虑,您应该评估您是否真的想这样做。想一想:
对于像您想象的那样执行的整个层次结构查询,单表继承策略通常是最快的。它可以使用单个查询执行整个层次结构和具体实体操作,无需连接或联合。
单表和连接继承策略确保层次结构中的所有实体都具有不同的键,而表每类策略不一定是这种情况。
单表和连接继承策略促进了涉及抽象超类的关系;每类表策略并没有很好地支持这些。
对 table-per-class 策略的支持是可选的。JPA 提供者不需要支持它,GlassFish 参考实现中的默认提供者实际上并不支持它。因此,不能保证依赖 table-per-class 的应用程序是可移植的。(您的提供商 Hibernate 确实支持它。)
你接着说,
但是,在这种情况下,我得到
java.sql.SQLSyntaxErrorException: ORA-00904: "KEY": invalid identifier. 似乎@Inheritance与@AttributeOverridefor@Id字段一起使用不起作用。
@AttributeOverride仅指定用于覆盖映射超类的属性以及嵌入类的字段和属性。如果它们出现在这些上下文中,它确实适用于@Id属性。它没有指定为从实体超类继承的持久字段和属性工作(尽管也没有指定为不工作),但请注意它不能使用单表或连接继承策略对此类属性工作。
如果@AttributeOverride碰巧对您有用,那么这种用途将是不可移植的。另一方面,JPA 没有别的东西可以完成你想要的。一个特定的持久性提供者可能有一个支持它的扩展,但 Hibernate 历史上没有这样做——从实体超类继承的所有属性都用相同的名称映射。
你还说,
我还想提到的另一件事是,我尝试使用
@MappedSuperclass而不是,@Inheritance但在这种情况下,我无法使用 abstactVehicle类型进行查询。
JPA 不为您的特定需求组合提供解决方案:
如果您不愿意更改其中任何一个,那么您将不得不依赖扩展。在这种情况下,您很幸运:Hibernate 支持多态查询,其中多态类型未映射为实体。因此,如果您愿意让您的应用程序显式地依赖于 Hibernate,那么您可能会到达您想要的位置。
具体来说,要在 Hibernate 中执行此操作,您将依赖于“隐式多态性”。为此,您将避免将超类映射为实体,根据您的经验,我猜它也不应该是映射的超类。它可以是一个普通的类,但它的属性不会是持久的,或者您可以使用接口代替。如果您的Vehicle类具有您想要持久化的属性,那么您可以将其更改为可嵌入的类。您还可以注释每个车辆实体以指定隐式多态性,例如:
@Entity
@Polymorphism(type = PolymorphismType.IMPLICIT)
// ...
public class Car implements Vehicle {
// ...
}
Run Code Online (Sandbox Code Playgroud)
Hibernate 文档声称隐式多态是默认的,但@Polymorphism为了清楚起见,我建议无论如何都应用注释。
| 归档时间: |
|
| 查看次数: |
1479 次 |
| 最近记录: |