如何在JPA中创建和处理复合主键

时间:2021-02-14 04:38:23

I want to have versions from the same data entry. In other words, I want to duplicate the entry with another version number.

我希望有来自相同数据条目的版本。换句话说,我想用另一个版本号复制条目。

id - Version will be the primary key.

id -版本将是主键。

How should the entity look like? How can I duplicate it with another version?

实体应该是什么样子?我怎么可以用另一个版本复制它?

id Version ColumnA

1   0      Some data
1   1      Some Other data
2   0      Data 2. Entry
2   1      Data

5 个解决方案

#1


172  

You can make an Embedded class, which contains your two keys, and then have a reference to that class as EmbeddedId in your Entity.

您可以创建一个嵌入式类,它包含两个键,然后在实体中有一个对该类的引用,如EmbeddedId。

You would need the @EmbeddedId and @Embeddable annotations.

您将需要@EmbeddedId和@ embed注解。

@Entity
public class YourEntity {
    @EmbeddedId
    private MyKey myKey;

    @Column(name = "ColumnA")
    private String columnA;

    /** Your getters and setters **/
}
@Embeddable
public class MyKey implements Serializable {

    @Column(name = "Id", nullable = false)
    private int id;

    @Column(name = "Version", nullable = false)
    private int version;

    /** getters and setters **/
}

Another way to achieve this task is to use @IdClass annotation, and place both your id in that IdClass. Now you can use normal @Id annotation on both the attributes

实现此任务的另一种方法是使用@IdClass注释,并将两个id都放在IdClass中。现在可以在两个属性上使用普通的@Id注释

@Entity
@IdClass(MyKey.class)
public class YourEntity {
   @Id
   private int id;
   @Id
   private int version;

}

public class MyKey implements Serializable {
   private int id;
   private int version;
}

#2


4  

The MyKey class must implement Serializable if you are using @IdClass

如果使用@IdClass, MyKey类必须实现Serializable

#3


1  

Key class:

主要类:

@Embeddable
@Access (AccessType.FIELD)
public class EntryKey implements Serializable {

    public EntryKey() {
    }

    public EntryKey(final Long id, final Long version) {
        this.id = id;
        this.version = version;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getVersion() {
        return this.version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (!(other instanceof EntryKey))
            return false;
        EntryKey castOther = (EntryKey) other;
        return id.equals(castOther.id) && version.equals(castOther.version);
    }

    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.id.hashCode();
        hash = hash * prime + this.version.hashCode();
        return hash;
    }

    @Column (name = "ID")
    private Long id;
    @Column (name = "VERSION")
    private Long operatorId;
}

Entity class:

实体类:

@Entity
@Table (name = "YOUR_TABLE_NAME")
public class Entry implements Serializable {

    @EmbeddedId
    public EntryKey getKey() {
        return this.key;
    }

    public void setKey(EntryKey id) {
        this.id = id;
    }

    ...

    private EntryKey key;
    ...
}

How can I duplicate it with another Version?

我如何复制它与另一个版本?

You can detach entity which retrieved from provider, change the key of Entry and then persist it as a new entity.

您可以分离从提供程序检索的实体,更改条目的键,然后将其持久化为一个新的实体。

#4


0  

The MyKey class (@Embeddable) should not have any relationships like @ManyToOne

MyKey类(@ embed able)不应该有任何关系,比如@ManyToOne

#5


-1  

When using the @IdClass annotation, another tip I found is the @Column annotation should go into the Entity class' fields (YourEntity in RohitJan's sample code).

在使用@IdClass注释时,我发现的另一个技巧是@Column注释应该进入实体类的字段(RohitJan示例代码中的YourEntity)。

#1


172  

You can make an Embedded class, which contains your two keys, and then have a reference to that class as EmbeddedId in your Entity.

您可以创建一个嵌入式类,它包含两个键,然后在实体中有一个对该类的引用,如EmbeddedId。

You would need the @EmbeddedId and @Embeddable annotations.

您将需要@EmbeddedId和@ embed注解。

@Entity
public class YourEntity {
    @EmbeddedId
    private MyKey myKey;

    @Column(name = "ColumnA")
    private String columnA;

    /** Your getters and setters **/
}
@Embeddable
public class MyKey implements Serializable {

    @Column(name = "Id", nullable = false)
    private int id;

    @Column(name = "Version", nullable = false)
    private int version;

    /** getters and setters **/
}

Another way to achieve this task is to use @IdClass annotation, and place both your id in that IdClass. Now you can use normal @Id annotation on both the attributes

实现此任务的另一种方法是使用@IdClass注释,并将两个id都放在IdClass中。现在可以在两个属性上使用普通的@Id注释

@Entity
@IdClass(MyKey.class)
public class YourEntity {
   @Id
   private int id;
   @Id
   private int version;

}

public class MyKey implements Serializable {
   private int id;
   private int version;
}

#2


4  

The MyKey class must implement Serializable if you are using @IdClass

如果使用@IdClass, MyKey类必须实现Serializable

#3


1  

Key class:

主要类:

@Embeddable
@Access (AccessType.FIELD)
public class EntryKey implements Serializable {

    public EntryKey() {
    }

    public EntryKey(final Long id, final Long version) {
        this.id = id;
        this.version = version;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getVersion() {
        return this.version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (!(other instanceof EntryKey))
            return false;
        EntryKey castOther = (EntryKey) other;
        return id.equals(castOther.id) && version.equals(castOther.version);
    }

    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.id.hashCode();
        hash = hash * prime + this.version.hashCode();
        return hash;
    }

    @Column (name = "ID")
    private Long id;
    @Column (name = "VERSION")
    private Long operatorId;
}

Entity class:

实体类:

@Entity
@Table (name = "YOUR_TABLE_NAME")
public class Entry implements Serializable {

    @EmbeddedId
    public EntryKey getKey() {
        return this.key;
    }

    public void setKey(EntryKey id) {
        this.id = id;
    }

    ...

    private EntryKey key;
    ...
}

How can I duplicate it with another Version?

我如何复制它与另一个版本?

You can detach entity which retrieved from provider, change the key of Entry and then persist it as a new entity.

您可以分离从提供程序检索的实体,更改条目的键,然后将其持久化为一个新的实体。

#4


0  

The MyKey class (@Embeddable) should not have any relationships like @ManyToOne

MyKey类(@ embed able)不应该有任何关系,比如@ManyToOne

#5


-1  

When using the @IdClass annotation, another tip I found is the @Column annotation should go into the Entity class' fields (YourEntity in RohitJan's sample code).

在使用@IdClass注释时,我发现的另一个技巧是@Column注释应该进入实体类的字段(RohitJan示例代码中的YourEntity)。