使用 Quarkus 的 JPA 中的复合主键是不是可能?
Posted
技术标签:
【中文标题】使用 Quarkus 的 JPA 中的复合主键是不是可能?【英文标题】:Are composite primary keys in JPA with Quarkus possible?使用 Quarkus 的 JPA 中的复合主键是否可能? 【发布时间】:2020-07-27 09:35:02 【问题描述】:如何使用 Quarkus 进行 JPA 声明复合键?
尝试在 Quarkus 的 @Entity
类中使用多个 @Id
注释,会导致错误:
Currently the @Id annotation can only be placed on a single field or method. Offending class is abc.model.Property
at io.quarkus.spring.data.deployment.generate.StockMethodsAdder.getIdAnnotationTargetRec(StockMethodsAdder.java:940)
但首先,在声明之后
interface PropertyRepository : CrudRepository<Property, Pair<String, abc.model.Entity>>
没有上面的声明,没有投诉,但没有可能主动管理Property
的实例。
如何规避此错误?
我正在处理两个 JPA 实体:
1.第一个叫Entity
(不要误认为是注解)
2.第二个叫Property
Entity
可以有 0..n 个 Property
实例。代码如下:
@Entity
data class Entity (
@Id
@Column(name = "entity_id", updatable = false)
var entityId: String? = null,
@Column(nullable = true)
var type: String? = null
)
@OneToMany(mappedBy = "entity")
var properties: List<Property>? = null
@Entity
data class Property (
@Id
@Column(name = "type")
var type: String? = null,
@Id
@ManyToOne
@JoinColumn(name = "entity_id")
private var entity: abc.model.Entity? = null
) : Serializable
如下将复合主键声明为@EmbeddedId
,并不能解决问题,因为在这种情况下,Quarkus 目前不允许除@Id
之外的其他注释:
@Entity
data class Entity (
@Id
@Column(name = "entity_id", updatable = false)
var entityId: String? = null,
@Column(nullable = true)
var type: String? = null
)
@OneToMany(mappedBy = "propertyId.entityId")
var properties: List<Property>? = null
interface PropertyRepository : CrudRepository<Property, PropertyId>
@Embeddable
data class PropertyId (
var type: String? = null,
@Column(name = "entity_id")
private var entityId: String? = null
) : Serializable
@Entity
data class Property (
@EmbeddedId
var propertyId: PropertyId? = null,
@Column(name = "constant_value")
var constantValue: String? = null
)
java.lang.IllegalArgumentException: Currently only Entities with the @Id annotation are supported. Offending class is abc.model.Property
at io.quarkus.spring.data.deployment.generate.StockMethodsAdder.getIdAnnotationTargetRec(StockMethodsAdder.java:932)
【问题讨论】:
正如错误所说,你不能有两次 Id 注释,如果 Property 有一个复合键,那么你必须为它创建一个新类 @lucsbelt 但是新类仍然会有两次 Id 注释。那么,这怎么可能是一个解决方案? 您有两种选择:使用 Embeddable(我更喜欢这个)或使用 IdClass 注释查看此示例objectdb.com/java/jpa/entity/id#Composite_Primary_Key @lucsbelt 这些替代方案均不适用于 Quarkus。请参阅我的问题的补充内容。 这是一个缺失的功能。能否请您开张票,以便我们处理? 【参考方案1】:有可能,您的实体必须扩展 PanacheEntityBase 并使用类级别注释 @Table,@Entity,@IdClass(PK.class),其中 Pk 是具有复合主键字段的 POJO,然后您必须声明您的实体中带有 @Id 注释的相同字段。例如:
@Entity()
@Table(name = "agent")
@IdClass(AgentPK.class)
public class AgentBRA extends PanacheEntityBase
@Id
public Integer idUsuario;
@Id
public Integer idAgent;
和 AgentPk:
public class AgentPK implements Serializable
protected Integer idUsuario;
protected Integer idAgent;
// getters setters and hascode and equals methods
【讨论】:
以上是关于使用 Quarkus 的 JPA 中的复合主键是不是可能?的主要内容,如果未能解决你的问题,请参考以下文章
具有父复合 pk 的 JPA OneToMany 是子主键派生实体问题的一部分