Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA table with 2 primary key fields

I have a table which contains only 2 fields. The table has a composite PK formed by these two fields.

When using Netbeans for creating entity beans from database, the entity bean is not created automatically like other tables that have more than 2 fields.

So I guess I need to create the entity bean myself. What is the best practice for creating this entity bean? Does it have to contain COMPOSITE KEY object or not?

like image 347
user2046810 Avatar asked Feb 06 '13 12:02

user2046810


People also ask

How do I make two columns a primary key in JPA?

A composite primary key, also called a composite key, is a combination of two or more columns to form a primary key for a table. In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations.

Can an entity have 2 primary keys?

A primary key is a field or set of fields with values that are unique throughout a table. Values of the key can be used to refer to entire records, because each record has a different value for the key. Each table can only have one primary key.

Can we have multiple @ID in JPA?

So yes, you can have more than one @Id. Or is it @EmbeddedId? I can't remember if @EmbeddedId is currently there, or if it is still in discussion by the JSR group for the next version of JPA. JPA 1.0 currently supports two different approaches for compound PKs.

How do you declare a composite primary key in JPA?

Configuring a JPA Entity Composite Primary Key Class It must be public and must have a public no-argument constructor. If you use property-based access, the properties of the primary key class must be public or protected. It must be serializable. It must define equals and hashCode methods.


1 Answers

I don't use NetBeans so I can't really say anything about its mapping tools.

For mapping a composite key, there are a couple of options. You can

  • Define a separate @Embeddable object with the PK fields and use it as @EmbeddedId in your @Entity class

    @Embeddable
    public class MyCompositePK { 
        @Column
        private String fieldA;
        @Column
        private String fieldB;
    }
    @Entity 
    public class MyBean { 
        @EmbeddedId
        private MyCompositePK id;
        @Column
        private String fieldC;
    }
    
  • Define a non-mapped POJO with the PK fields and use it as @IdClass in the @Entity.

    @Entity
    @IdClass(value=ClassAB.ClassABId.class)
    public class ClassAB implements Serializable {
        private String idA;
        private String idB;
    
        @Id
        @Column(name="ID_A")
        public String getIdA(){ return idA; }
        public void setIdA(String idA){ this.idA = idA; }
    
        @Id
        @Column(name="ID_B")
        public String getIdB(){ return idB; }
        public void setIdB(String idB){ this.idB = idB; }
    
        static class ClassABId implements Serializable {
            private String idA;
            private String idB;
    
            public String getIdA(){ return idA; }
            public void setIdA(String idA){ this.idA = idA; }
    
            public String getIdB(){ return idB; }
            public void setIdB(String idB){ this.idB = idB; }
    
            // implement equals(), hashcode()
        }
    }
    

    In this example ClassABId is a static inner class just for convenience.

These options are also explained in Pascal Thivent's excellent answer to this question: How to map a composite key with Hibernate?.

This related question discusses differences between these approaches: Which anotation should I use: @IdClass or @EmbeddedId. Notice the fields' declaration gets duplicated with the @IdClass approach.

Anyhow, I don't think there's an alternative to creating two classes. That's why I asked this question : Mapping a class that consists only of a composite PK without @IdClass or @EmbeddedId. It seems there's an hibernate-specific feature for this.

As a side note, if you've got control over the DB structure, you might also consider avoiding composite keys. There are some reasons to do so.

like image 119
Xavi López Avatar answered Sep 24 '22 15:09

Xavi López