1

我有两个实体如下:

  • Invoice
    • 主键是InvoiceId
    • 其他感兴趣的列是[OrgId, VendorId, VendorInvoiceId]
  • InvoiceState
    • 主键是InvoiceStateId
    • 其他感兴趣的列是[OrgId, VendorId, VendorInvoiceId]

“其他感兴趣的列”在两个表中形成唯一键,除了第二个表InvoiceState可以包含在第一个表中没有对应记录的记录Invoice

在实体层,我想定义Invoice实体以包含对具有定义关系的InvoiceState实体@OneToOne的引用,@JoinColumns如下所示:

@OneToOne
@JoinColumns
({
    @JoinColumn(name="OrgId", referencedColumnName="OrgId"),
    @JoinColumn(name="VendorId", referencedColumnName="VendorId"),
    @JoinColumn(name="VendorInvoiceId", referencedColumnName="VendorInvoiceId")
})

但这会引发一个异常,即两个实体中的外键计数不相同。我什至没有在这两个表之间定义外键。

有没有办法定义@OneToOne两个不共享外键但有一组可以在期间使用的列的实体之间的关系JOIN

4

2 回答 2

1

我建议将上述 3 列映射为componentusing@Embeddable并使用组件进行映射,使用@Embedded和定义连接条件。

例如下面:

  @Embeddable
  public class ReferenceInfo {

      private Long orgId = null;
      private Long vendorId= null;
      private Long vendorInvoiceId= null;

      .........
      .........
  }


  @Entity
  public class Invoces{

     private Long invoiceId = null;
     private ReferenceInfo refInfo = null;
     private InvoiceStates invoiceStates = null;

     @Id
     public Long getInvoiceId(){
        return invoiceId;
     }

     ......

      @Embedded
      public ReferenceInfo getRefInfo(){
        ....
      }

      @OneToOne(mappedBy="refInfo"))
      public InvoiceStates getInvoiceStates(){
        return invoiceStates;
      }
  }


  @Entity
  public class InvoiceStates {

     private Long invoiceStateId = null;
     private ReferenceInfo refInfo = null;

     @Id
     public Long getInvoiceStateId(){
        return invoiceStateId;
     }

     ......

      @Embedded
      public ReferenceInfo getRefInfo(){
        ....
      }
  }
于 2012-10-21T04:36:44.757 回答
1

如果这三个字段是唯一的,您可以将它们标记为 InvoicesState 实体的 PK,然后允许 state 在 oneToOne 中引用它们。用于 JPA 的 PK 不需要匹配表 id,它只需要是唯一的。

一些提供者确实允许在映射中引用非 PK 字段。但并不总是建议这样做,因为实体通常缓存在 PK 上,因此您可能会获得额外的数据库命中来解析引用。在 Eclipselink 中,您可以通过仅使用其中一个字段来伪造映射,并在描述符定制器中更正映射以将其余字段添加到关系中。

于 2012-10-21T13:34:17.173 回答