【问题标题】:Composite Primary key in JPA with Key value structure in child tableJPA中的复合主键与子表中的键值结构
【发布时间】:2018-06-24 10:42:24
【问题描述】:

我有 2 个具有 OneToMany 关系的表,并创建了如下实体

表 1- Network 的主键为 networkId

表 2- NetworkAttributes 将 FK 作为 networkId,但通过组合“networkId”和“name”,记录应被视为唯一的列 [属性表中的名称列不存在于网络表中] 在这里我存储了多个网络参数的默认值,并且参数可以在不同的网络下重复,如下表结构在“网络属性",

表结构:-

网络表

 networkID | networkName | networkType

  H123M       nrouter      X
  N123Y       testR        J

NetworkAttributes Table:[键值类存储默认值]

 networkID   | name          |   value

  H123M       maxIpUser          10
  H123M       maxRouterUser      15
  N123Y       maxIpUser          23
  N123Y       maxRouterUser      25

网络实体:-

@Entity
@Table(name = "NETWORK")
public class Network implements Serializable {

private static final long serialVersionUID = 1L;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;

@Id
@NotNull
@Column (name = "NETWORKID")
private String networkId;

@Column (name = "networkName")
private String networkName;

@Column (name = "networkType")
private String networkType;

@Column (name = "onlyActive")
private boolean onlyActive;

@OneToMany (fetch = FetchType.LAZY, mappedBy = "network")
private List<NetworkAttributes> networkAttributes;

  // Setter / Getter

网络属性实体:-

 @Entity
 @Table (name = "NETWORK_ATTRIBUTES")
 public class NetworkAttributes implements Serializable {

private static final long serialVersionUID = 1L;

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

@Column (name = "value")
private String value;

@ManyToOne (fetch = FetchType.LAZY)
@JoinColumn (name = "network_Id")
private Network network;

// setter / getter

问题: 使用此表结构,我无法在 Network Attributes 表中为相同的网络插入不同的参数。给出唯一的约束错误。有什么好的建议

例如,您可以看到我正在尝试在下面插入记录,但由于 networkId 为 FK,因此不允许插入第 2 和第 4 记录。

  H123M       maxIpUser          10
  H123M       maxRouterUser      15
  N123Y       maxIpUser          23
  N123Y       maxRouterUser      25

【问题讨论】:

标签: hibernate jpa spring-data-jpa


【解决方案1】:

这是一个“派生身份”,所以NetworkAttributes 可以像这样映射到@EmbeddedId

@Embeddable
public class NetworkAttributesId {
    String name;
    String networkId; // corresponds to PK type of Network
}


@Entity
@Table (name = "NETWORK_ATTRIBUTES")
public class NetworkAttributes implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    NetworkAttributesId id;

    @ManyToOne (fetch = FetchType.LAZY)
    @JoinColumn (name = "network_Id")
    @MapsId("networkId") // maps networkId attribute of embedded id
    private Network network;

    @Column (name = "value")
    private String value;

    ...
}

在第 2.4.1 节的JPA 2.2 spec 中讨论了派生的身份(带有示例)。

【讨论】:

  • @Brain... 谢谢我已经使用 EmbeddedId 使用不同的方式解决了这个问题。在 Embeddable 类中,我使用了父类的 ManytoOne 关系。成功了
  • @Brain。我注意到我的实现和你的建议之间的细微差别.. @MapsId("networkId") 。这种方式是强制的吗?
  • @Manu ,如果使用嵌入式 @ManyToOne 适合您,我想这不是强制性的。 :) 但是,我认为 JPA 2.x 仅针对这种情况添加了 @MapsId 注释。有什么问题吗?
猜你喜欢
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2020-10-04
  • 1970-01-01
  • 2015-05-26
  • 2013-03-19
相关资源
最近更新 更多