使用复合键

时间:2017-06-28 14:15:27

标签: jpa spring-data-jpa composite-key

我试图弄清楚如何使用复合键映射实体,并且具有属性,该属性是连接表上的复合键的一部分。

我在父表上有SalesOrderNumber,在子表上有3个属性,其中一个是SalesOrderNumber。

对于主表(SalesHeader)我试图使用SalesOrderNumber作为连接列来获取SalesOrder实体,这样当我检索SalesHeader时,我也有一个SalesOrder对象。

提前致谢。

数据库

SalesHeader表

ClientKey - PK, int
InvoiceNumber - PK, String
InvoiceBillingDateKey - PK, int
SalesOrderNumber - String, not null

SalesOrder表

ClientKey - PK, int
SalesOrderNumber - PK, String
SalesOrderCreatedOnDateKey - PK, int

映射

SalesHeader JPA对象

@EmbeddedId
    private FactSalesHeaderKey  factSalesHeaderKey;

@OneToOne(fetch=FetchType.EAGER)

@JoinColumn(name = "SalesOrderNumber", referencedColumnName="SalesOrderNumber", nullable=false)

private FactSalesOrder factSalesOrder;  <==== TRYING TO SET THIS

public FactSalesOrder getFactSalesOrder() {
    return factSalesOrder;
}

public void setFactSalesOrder(FactSalesOrder factSalesOrder) {
    this.factSalesOrder = factSalesOrder;
}

SalesOrderKey - 复合PK对象

@Embeddable

    public class FactSalesOrderKey implements Serializable{

        private static final long serialVersionUID = 1L;
        @Column(name="ClientKey")
        private Long  clientKey;
        @Column(name="SalesOrderNumber")
        private String salesOrderNumber;
        @Column(name="SalesOrderCreatedOnDateKey")
        private Long salesOrderCreatedOnDateKey;
    }

SalesOrder - JPA对象

@Entity

    public class FactSalesOrder {

    @EmbeddedId
    private FactSalesOrderKey factSalesOrderKey;
    @Column(name="OverallBillingStatus", nullable = true)
    private Long overallBillingStatus;
    @Column(name="OverallDeliveryStatus", nullable = true)
    private Long overallDeliveryStatus;
    @Column(name="OverallOrderStatus", nullable = true)
    private Long overallOrderStatus;

}

1 个答案:

答案 0 :(得分:0)

  1. 你要求一对一还是一对多?你问题标题是一对多,但代码片段有一对一的注释。此外,如果您有一对一,为什么要将它们存储在单独的表中?如果你有一对多关系,那么你需要一个连接表。
  2. 假设您具有一对多关系,那么您需要一组引用的对象和表中的映射属性,您可以在其中放置一对多的注释。另一方面,您需要为每个属性放置多对一注释和连接列注释,其中包含一个连接列注释,该属性是引用表中复合键的一部分。

    public class SalesHeader {
      @EmbeddedId
      private SHKey shKey;
      @OneToMany(mappedBy="salesHeader")
      private Set<SalesOrder> salesOrders;
    
    }
    
    public class SalesOrder {
    @EmbeddedId
    private SOKey soKey;
    @ManyToOne
    @JoinColumns({@JoinColumn(name="clientKey",referencedColumnName="clientKey"),@JoinColumn(name="invoiceNumber",referencedColumnName="invoiceNumber"),@JoinColumn(name="invoiceBillingDateKey",referencedColumnName="invoiceBillingDateKey")})
    private SalesHeader salesHeader;
    
    }
    
    public class SHKey{
     @Column(name="clientKey")
     private Long clientKey;
     @Column(name="invoiceNumber")
     private String InvoiceNumber;
     @Column(name="invoiceBillingDateKey")
     private Long InvoiceBillingDateKey;
    }
    
  3. 希望它有所帮助。

    <强>更新

    我认为你不可能以这种方式实现你的要求。需要将引用表中的复合键的所有列与引用表进行一对一关系,然后才能定义连接列。除了ClientKeySalesOrderNumber之外,您需要在SalesOrderCreatedOnDate表格中使用SalesHeader属性来salesHeader.getSalesOrder()调用此类工作。正如您所说的那样,您不必自由更改数据库架构,为实现此目的,您可以为给定的salesOrderNumber

    编写查询

    一对一映射的示例代码 -

      @Entity
      public class SalesHeader implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @EmbeddedId
    private SHKey shkey;
    
    
    @OneToOne
    @JoinColumns({@JoinColumn(name="clientKey",referencedColumnName="clientKey",updatable = false,insertable = false),@JoinColumn(name="SalesOrderNumber",referencedColumnName="SalesOrderNumber"),@JoinColumn(name="SalesOrderCreatedOnDateKey",referencedColumnName="SalesOrderCreatedOnDateKey",updatable = false,insertable = false)})
    private SalesOrder salesOrder;
    
    
    }
    
    @Entity
    public class SalesOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    private SOKey sokey;
    
    
     }
    
    @Embeddable
    public class SHKey implements Serializable {
    
    @Column(name = "clientKey")
    private Long clientKey;
    @Column(name = "invoiceNumber")
    private String InvoiceNumber;
    @Column(name = "invoiceBillingDateKey")
    private Long InvoiceBillingDateKey;
    }
    
    @Embeddable
    public class SOKey implements Serializable{
    
    @Column(name = "ClientKey")
    private Long clientKey;
    @Column(name = "SalesOrderNumber")
    private String salesOrderNumber;
    @Column(name = "SalesOrderCreatedOnDateKey")
    private Long salesOrderCreatedOnDateKey;
    }
    

    您可以实现使用命名查询或条件API的要求。