将复合外键映射到复合主键

时间:2018-06-19 14:59:52

标签: java hibernate jpa

我在jpa / hibernate中映射复合键时遇到问题。父实体和子实体都具有复合主键。

当父实体具有简单密钥而子实体具有复合密钥时,我已经能够使用@mapsId。

在休眠文档中,他们在映射中使用@JoinCoumns来演示映射两个组合键。但是在他们的示例中,不清楚这些列引用的定义位置。

我有以下内容:

@Embeddable
public class PriceRequestLegKey implements Serializable {
   @Column(name = "leg_request_id")
   private String requestId;
   @Column(name = "display_index")
   private int displayIndex;
   ...
}

@Embeddable
public class AllocationKey implements Serializable {

   @Column(name = "leg_request_id")
   private String requestId;
   @Column(name = "display_index")
   private int displayIndex;
   @Column(name = "allocation_index")
   private int allocationIndex;
   ...
}

@Entity(name = "PriceRequestLeg")
public class PriceRequestLegModel {

   @EmbeddedId
   private PriceRequestLegKey legKey;
   @OneToMany(cascade = CascadeType.ALL)
   @JoinColumns({
      @JoinColumn(name = "leg_request_id", referencedColumnName = "leg_request_id"),
      @JoinColumn(name = "display_index", referencedColumnName = "display_index")
   })
   private List<AllocationModel> allocations;
   ...
}

@Entity(name = "Allocation")
public class AllocationModel {

   @EmbeddedId
   private AllocationKey allocationKey;
   @ManyToOne
   @MapsId
   @JoinColumns({
      @JoinColumn(name = "leg_request_id", referencedColumnName = "leg_request_id"),
      @JoinColumn(name = "display_index", referencedColumnName = "display_index")
   })
   private PriceRequestLegModel leg;
   ...
}

在运行时保存时会出现以下异常:

org.springframework.orm.jpa.JpaSystemException: could not get a field value by reflection getter of com.lbg.legato.rfq.data.entity.AllocationKey.displayIndex; nested exception is org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.lbg.legato.rfq.data.entity.AllocationKey.displayIndex

我认为这是虚假的,因为有吸气剂和吸气剂。如果我在priceRequestLegModel上使用mapledBy =“ leg”,在AllocationModel上使用@MapsId,也会遇到相同的错误。有人可以指出我在做什么错吗?

1 个答案:

答案 0 :(得分:0)

您应该将mappedBy="leg"恢复到PriceRequestLegModel @OneToMany批注:

@Entity(name = "PriceRequestLeg")
public class PriceRequestLegModel {

   @EmbeddedId
   private PriceRequestLegKey legKey;
   @OneToMany(mappedBy="leg", cascade = CascadeType.ALL)
   private List<AllocationModel> allocations;
   ...
}

然后,您应将AllocationKey更改为引用PriceRequestLegKey

@Embeddable
public class AllocationKey implements Serializable {

   PriceRequestLegKey legKey; // corresponds to PK type of PriceRequestLegModel
   @Column(name = "allocation_index")
   private int allocationIndex;
   ...
}

然后适当设置Allocation.leg @MapsId批注的值:

@Entity(name = "Allocation")
public class AllocationModel {

   @EmbeddedId
   private AllocationKey allocationKey;
   @ManyToOne
   @MapsId("legKey")
   @JoinColumns({
      @JoinColumn(name = "leg_request_id", referencedColumnName = "leg_request_id"),
      @JoinColumn(name = "display_index", referencedColumnName = "display_index")
   })
   private PriceRequestLegModel leg;
   ...
}

JPA 2.2 spec第2.4.1节中有类似的例子。