How to JPA-declare a composite key with Quarkus?
Trying to use multiple @Id
annotations in an @Entity
class with Quarkus, results in the error:
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)
But first, after declaring
interface PropertyRepository : CrudRepository<Property, Pair<String, abc.model.Entity>>
Without the declaration above, there are no complaints, but no possibility to actively manage instances of Property
.
How to circumvent this error?
I'm dealing with two JPA Entities:
1. the first one named Entity
(don't mistake for the annotation)
2. the second one named Property
An Entity
can have 0..n instances of Property
. The code is as follows:
@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
Declaring the composite primary key as an @EmbeddedId
as follows, does not solve the problem, as Quarkus currently doesn't allow other annotations than @Id
in this case:
@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)
In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations. In order to define the composite primary keys, we should follow some rules: The composite primary key class must be public. It must have a no-arg constructor.
The following rules apply for composite primary keys: The primary key class must be public and must have a public no-arg constructor. If property-based access is used, the properties of the primary key class must be public or protected. The primary key class must be serializable .
Primary keys must contain unique values. A primary key column cannot have NULL values. A table can have only one primary key, which may consist of single or multiple fields. When multiple fields are used as a primary key, they are called a composite key.
it is possible, your entity must extend PanacheEntityBase and use class level annotation @Table,@Entity,@IdClass(PK.class), where Pk is a POJO with fields of the composite primary key, then you have to declare the same fields with @Id annotation in your entity. eg:
@Entity()
@Table(name = "agent")
@IdClass(AgentPK.class)
public class AgentBRA extends PanacheEntityBase {
@Id
public Integer idUsuario;
@Id
public Integer idAgent;
and AgentPk:
public class AgentPK implements Serializable{
protected Integer idUsuario;
protected Integer idAgent;
// getters setters and hascode and equals methods
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With