【问题标题】:Mapping a composite foreign key to a composite primary key将复合外键映射到复合主键
【发布时间】:2018-11-28 14:23:52
【问题描述】:

我在 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

我认为这是虚假的,因为有 getter 和 setter。如果我在 priceRequestLegModel 上使用 mappedBy="leg" 并在 AllocationModel 上使用 @MapsId,我也会得到同样的错误。谁能指出我在这里做错了什么?

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    您应该将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 节中有一些类似的示例。

    【讨论】:

    • 布莱恩,非常感谢。更改 AllocationKey 以引用 PriceRequestLegKey 解决了它。非常感谢。
    猜你喜欢
    • 2017-08-06
    • 2019-04-22
    • 2012-04-30
    • 2020-10-04
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    相关资源
    最近更新 更多