ChatGPT解决这个技术问题 Extra ChatGPT

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

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

id - Version 将是主键。

实体应该是什么样子?如何将其复制到另一个版本?

id Version ColumnA

1   0      Some data
1   1      Some Other data
2   0      Data 2. Entry
2   1      Data
使用 @IdClass 注释时,我发现的另一个提示是 @Column 注释应该进入实体类的字段(RohitJan 的示例代码中的 YourEntity)。

p
pixel

您可以创建一个 Embedded class,其中包含您的两个键,然后在您的 Entity 中将该类作为 EmbeddedId 引用。

您将需要 @EmbeddedId@Embeddable 注释。

@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 **/
}

完成此任务的另一种方法是使用 @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;
}

EmbeddedId 是否可以将 @Generatedvalue 用于 Id
@凯瑟。我所知道的。不,您必须在 KeyClass 实例中为它们显式设置值,然后在您的实体中设置该键类实例。
@凯瑟。 @GeneratedValue 只能用于为主键生成键值,不能为复合键生成组合。
@凯瑟。请参阅 JPA 2.0 规范的 Section - 11.1.17 GeneratedValue Annotation。它清楚地表明,@GeneratedValue 只能与简单的主键一起使用。
@RohitJain 只有一件事:您实际上不能将嵌入式类公开(需要在其自己的文件中公开)
B
Bö macht Blau

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


V
Victor Stafusa

关键类:

@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
@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;
    ...
}

如何将其复制到另一个版本?

您可以分离从提供者检索到的实体,更改 Entry 的键,然后将其作为新实体保存。


是否可以在 Entrykey AUTOGENERATED 中定义 id。订购类似的东西@GeneratedValue(strategy = GenerationType.IDENTITY)
我也想知道如何计算 2 个长主键的哈希值。至于类EntryKey中方法hashCode中的hashprime,你能告诉我这个想法是从哪里来的吗?
R
Ranuka

MyKey 类(@Embeddable)不应该有任何像 @ManyToOne 这样的关系


为什么不?你看过这个example吗?