不共享任何外键关系的JPA实体之间的@OneToOne关系

时间:2012-10-21 04:09:24

标签: java jpa one-to-one

我有两个实体如下:

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

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

在实体层,我想定义Invoice实体,以包含对定义了Invoice关系的InvoiceState实体的引用,其中@OneToOne如下:

@JoinColumns

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

有没有办法在两个不共享外键的实体之间定义@OneToOne @JoinColumns ({ @JoinColumn(name="OrgId", referencedColumnName="OrgId"), @JoinColumn(name="VendorId", referencedColumnName="VendorId"), @JoinColumn(name="VendorInvoiceId", referencedColumnName="VendorInvoiceId") }) 关系,但有一组可以在@OneToOne期间使用的列?

2 个答案:

答案 0 :(得分:1)

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

e.g。下面:

  @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(){
        ....
      }
  }

答案 1 :(得分:1)

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

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