java - JPA:如何使用派生 IdClass 实现复合主键?

标签 java jpa eclipselink

我正在使用 JPA 实体实现以下表结构,其中显示的属性代表 PK/FK 列。 protocolId 是自动生成的,并在调用 persist() 之前在所有实体中设置为 null。整个结构被立即存储。

Table relationships

help of a stackoverflow userJPA spec ,我解析了 Position 中的派生身份:

@Entity
@Table(name="...")
@IdClass(PositionID.class)
public class Position {

    @Id
    @Column(name = "POSITION_ID")
    private int positionId;

    @Id
    @ManyToOne(...)
    @JoinColumn(name="PROTOCOL_ID")
    private Protocol protocol;    


    @OneToMany(mappedBy="position")
    private Collection<Item>
}


public class PositionID implements Serializable{
    private int protocol;
    private int positionId;
}

上述关系有效,但我在 Item 中实现派生标识时遇到问题。

这是我根据2.4.1.3派生身份示例章节中的规范编写的版本:

@Entity
@Table(name="...")
@IdClass(ItemId.class)
public class Item {

    @Id
    @Column(name = "ITEM_NAME")
    private String itemName;

    @Id
    @ManyToOne(...)
    @JoinColumns({
        @JoinColumn(name="POSITION_ID", referencedColumnName="POSITION_ID"),
        @JoinColumn(name="PROTOCOL_ID", referencedColumnName="PROTOCOL_ID")
    })
    private Position position;
}

public class ItemId implements Serializable {
    private String itemName;
    private PositionId position;
}

不幸的是,这会导致以下错误:

Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [null] and those of the entity bean class [class ......Item] must correspond and their types must be the same.

如何实现Item的身份?

最佳答案

我认为你可以使用组合主键!

在您的主要实体(项目)中,您使用以下内容:

@EmbeddedId
private CombinedPK id;

并在CombinedPK中设置:

@Embeddable // Annotation on class level
public class CombinedPK {
    ...
    @Column(name = "positionId")
    private Integer positionId;

    @Column(name = "protocolId")
    private Integer protocolId;
}

然后可以像平常一样映射组合PK中的列,每个列都有自己。

此外,从您的 position 字段中删除 @Id 注释,并将 insertable=false, updatable=false 添加到您的 @ JoinColumn 注释。

问题在于,在 Java 模型中,您拥有(并且需要)来自 SQL 的相同数据的两种不同表示形式:您需要对主键进行建模和注释,还需要外键关系。 JPA 不能很好地处理这个问题,并且 JPA 还禁止更改记录的主键。如果您可以更改数据库,您会发现添加 'SERIAL' 更容易列添加到您的项目表中,并将其用作主键(并在外键列上添加复合唯一约束)。

关于java - JPA:如何使用派生 IdClass 实现复合主键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32651686/

相关文章:

java - 为每个创建的类调用构造函数

java - 使用方法的返回值和保留它们有什么区别?

java - 为什么 javac -cp 选项区分大小写,而 java -cp 选项不区分大小写?

java - 如何在未来刷新实体?

java - OpenJPA 1 - 未创建序列表

java - jpa发现问题

java - 无法将加密格式从 Java 复制到 PHP

hibernate - 二级缓存 - 为什么不缓存所有实体?

java - 如何在 persistence.xml 文件中包含外部实体

java - JPA DescriptorEventAdapter ChangeSet 始终为空