使用ID和版本列映射一对多关系



我有两个JPA实体ParentChild

父母有@Id@Version

对于每个父母(ID和版本为fks)都有多个孩子。

@Entity
@Table(name = "parent")
public class ParentDao implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "parent_id")
    private Long parentId;
    @Version
    @Column(name = "parent_version", updatable = false)
    private Long parentVersion;
...
}

@Entity
@Table(name = "child")
public class ChildDao implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "child_id")
    private Long childId;
    @Column(name = "parent_id", updatable = false)
    private Long parentId;
    @Column(name = "parent_id", updatable = false)
    private Long parentVersion;
...
}

如果该版本没有约束,则孩子对父母的fk是。

@OneToMany(mappedBy = "parentId", cascade = CascadeType.ALL)
private Set<ChildDao> children = new HashSet<>(0);

Hibernate将版本视为一个特殊字段,因为在属性级别有@Version注释集。

因此,我可以想象,也许他们在实施一对一的关系时会想到这一点。

尽管如此,可能会有一个更通用的解决方案。

因此,如何将版本添加为一个关系中的约束?

在rdbms中,fk引用了pk。因此,孩子FK必须引用父实体标识符,对吗?

version永远不应形成FK,因为该版本不断变化,而FK不应因为它必须引用A 不变 fk。

如果您需要一种自定义表达收藏的方式,则应使用@JoinFormla而不是@JoinColumn

更多,Child映射无论如何都是错误的,因为您正在复制parent_id映射:

@Column(name = "parent_id", updatable = false)
private Long parentId;
@Column(name = "parent_id", updatable = false)
private Long parentVersion;

也许您想拥有:

@Column(name = "parent_id", updatable = false)
private Long parentId;
@Column(name = "parent_version", updatable = false)
private Long parentVersion;