Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are composite primary keys in JPA with Quarkus possible?

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)
like image 914
Min-Soo Pipefeet Avatar asked Apr 14 '20 15:04

Min-Soo Pipefeet


People also ask

How does JPA implement composite primary key?

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.

How can I get composite key in JPA with Hibernate?

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 .

Can primary key be composite?

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.


1 Answers

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
  
like image 75
Salvatore Pannozzo Capodiferro Avatar answered Oct 17 '22 08:10

Salvatore Pannozzo Capodiferro