JPA Composite Key + Sequence

后端 未结 4 374
春和景丽
春和景丽 2021-02-02 14:51

Is it possible in plain JPA or JPA+Hibernate extensions to declare a composite key, where an element of the composite key is a sequence?

This is my composite class:

相关标签:
4条回答
  • 2021-02-02 15:02

    Try like this:

    @TableGenerator(name = "canonicalKeys", allocationSize = 1, initialValue = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "canonicalKeys")
    @Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true)
    public String getCanonicalId() {
        return canonicalId;
    }
    

    In this way instead of using a sequence you can use a table.

    0 讨论(0)
  • 2021-02-02 15:09

    Using @GeneratedValue for composite PKs is not specified withi JPA 2 spec.

    From the JPA spec:

    11.1.17 GeneratedValue Annotation

    The GeneratedValue annotation provides for the specification of generation strategies for the values of primary keys. The GeneratedValue annotation may be applied to a primary key property or field of an entity or mapped superclass in conjunction with the Id annotation.[97] The use of the GeneratedValue annotation is only required to be supported for simple primary keys. Use of the GeneratedValue annotation is not supported for derived primary keys.

    Note that under a different scenario, you can have a parent entity with a simple PK (@Id) that uses @GeneratedValue, and then have a child entity that has a composite PK that includes the generated Id from the parent, plus another column.

    • Give the child a @ManyToOne relationship to the parent entity, so that it inherits the generated ID in a FK column.
    • Then give the child a composite PK, via @IdClass specified against the entity, plus two @Id columns within the entity.
    @Entity
    public class ParentEntity {
    
           @Id
           @GenerateValue(IDENTITY) // If using DB auto-increment or similar
           int id;
    
           // ...
    }
    
    @Entity
    @IdClass(ChildId.class)
    public class ChildEntity {
       // The child table will have a composite PK:
       // (parent_ID, child_name)
           @Id 
           @ManyToOne
           int parentEntity;
    
           @Id
           String childName;
    
           String favoriteColor;  // plus other columns
    
           // ...
    
    }
    
    // child Id attributes have the same name as the child entity
    // however the types change to match the underlying PK attributes 
    // (change ParentEntity to int)
     public class ChildId implements Serializable {
    
            int parentEntity;
            String childName;
    
            public ChildId() { //... }
    
            // Add extra constructor & remove setter methods so Id objects are immutable
            public ChildId(int parentEntity, String childName) { //... }
    
    
            public int getParentEntity() { //... }
            // make Id objects immutable:
            //  public void setParentEntity(int parentEntity) { //... }
            public String getChildName() { //... }
            //  public void setChildName(String childName) { //... }
    }
    
    0 讨论(0)
  • 2021-02-02 15:11

    I notice that it appears your building a composite primary key like this example. While I was poking at a similar problem in my own database I wondered if maybe you could call the sql directly like:

    select nextval ('hibernate_sequence')

    I suppose that would be cheating though ;-)

    0 讨论(0)
  • 2021-02-02 15:26

    I believe that this is not possible with plain JPA.

    0 讨论(0)
提交回复
热议问题