【问题标题】:OneToOne JPA relation with composite primary key与复合主键的 OneToOne JPA 关系
【发布时间】:2019-11-25 14:15:09
【问题描述】:

我有这个不工作的双向 OneToOne 示例:

@Embeddable
public class SolicitudGUCDetalleId implements Serializable {

  @Column(name = "IDPEDIDO", insertable = false, updatable = false)
  @Size(max = 36)
  private String idPedido;

  @Column(name = "IDLINEA", precision = 10, scale = 0, insertable = false, updatable = false)
  private long idLinea;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCDET")
public class SolicitudGUCDetalle implements Serializable {

  @EmbeddedId
  private SolicitudGUCDetalleId id;

  @OneToOne(fetch = FetchType.LAZY, mappedBy = "solicitudGUCDetalle")
  private SolicitudGUCEnvio solicitudGUCEnvio;

  ...
}

@Embeddable
public class SolicitudGUCEnvioId implements Serializable {

  @Column(name = "IDPEDIDO", insertable = false, updatable = false)
  @Size(max = 36)
  private String idPedido;

  @Column(name = "IDLINEA", insertable = false, updatable = false)
  private long idLinea;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCENV")
public class SolicitudGUCEnvio implements Serializable {


  @EmbeddedId
  private SolicitudGUCEnvioId id;

  @OneToOne(fetch = FetchType.LAZY)
  @PrimaryKeyJoinColumns({
      @PrimaryKeyJoinColumn(name = "IDLINEA", referencedColumnName = "IDLINEA"),
      @PrimaryKeyJoinColumn(name = "IDPEDIDO", referencedColumnName = "IDPEDIDO")})
  private SolicitudGUCDetalle solicitudGUCDetalle;

  ...
}

我已阅读有关该问题的信息,并且我有两种可行的方法来实现这种关系。

1 - 对复合主键使用相同的类:

@Embeddable
public class SolicitudGUCId implements Serializable {

  @Column(name = "IDPEDIDO", insertable = false, updatable = false)
  @Size(max = 36)
  private String idPedido;

  @Column(name = "IDLINEA", precision = 10, scale = 0, insertable = false, updatable = false)
  private long idLinea;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCDET")
public class SolicitudGUCDetalle implements Serializable {

  @EmbeddedId
  private SolicitudGUCId id;

  @OneToOne(fetch = FetchType.LAZY, mappedBy = "solicitudGUCDetalle")
  private SolicitudGUCEnvio solicitudGUCEnvio;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCENV")
public class SolicitudGUCEnvio implements Serializable {

  @EmbeddedId
  private SolicitudGUCId id;

  @OneToOne(fetch = FetchType.LAZY)
  @PrimaryKeyJoinColumns({
      @PrimaryKeyJoinColumn(name = "IDLINEA", referencedColumnName = "IDLINEA"),
      @PrimaryKeyJoinColumn(name = "IDPEDIDO", referencedColumnName = "IDPEDIDO")})
  private SolicitudGUCDetalle solicitudGUCDetalle;

  ...
}

2 - 切换到 @OneToMany 关系并将相关实体存储在 Set 中:

@Embeddable
public class SolicitudGUCDetalleId implements Serializable {

  @Column(name = "IDPEDIDO", insertable = false, updatable = false)
  @Size(max = 36)
  private String idPedido;

  @Column(name = "IDLINEA", precision = 10, scale = 0, insertable = false, updatable = false)
  private long idLinea;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCDET")
public class SolicitudGUCDetalle implements Serializable {

  @EmbeddedId
  private SolicitudGUCDetalleId id;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "solicitudGUCDetalle")
  private Set<SolicitudGUCEnvio> solicitudes;

  ...
}

@Embeddable
public class SolicitudGUCEnvioId implements Serializable {

  @Column(name = "IDPEDIDO", insertable = false, updatable = false)
  @Size(max = 36)
  private String idPedido;

  @Column(name = "IDLINEA", insertable = false, updatable = false)
  private long idLinea;

  ...
}

@Entity
@Table(name = "TRIISOLIDGUCENV")
public class SolicitudGUCEnvio implements Serializable {

  @EmbeddedId
  private SolicitudGUCEnvioId id;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumns({
      @JoinColumn(name = "IDLINEA", referencedColumnName = "IDLINEA",
          nullable = false, insertable = false, updatable = false),
      @JoinColumn(name = "IDPEDIDO", referencedColumnName = "IDPEDIDO",
          nullable = false, insertable = false, updatable = false)})
  private SolicitudGUCDetalle solicitudGUCDetalle;

  ...
}

我想知道我是否可以按照我的第一个示例实现这种关系。如果答案是否定的,我想知道为什么。

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    这似乎是一个“派生的身份”;因此您可以尝试对选项 1 稍作改动:

    @Embeddable
    public class SolicitudGUCId implements Serializable {
    
        @Column(name = "IDPEDIDO", insertable = false, updatable = false)
        @Size(max = 36)
        private String idPedido;
    
        @Column(name = "IDLINEA", precision = 10, scale = 0, insertable = false, updatable = false)
        private long idLinea;
    
        ...
    }
    
    @Entity
    @Table(name = "TRIISOLIDGUCDET")
    public class SolicitudGUCDetalle implements Serializable {
    
        @EmbeddedId
        private SolicitudGUCId id;
    
        @OneToOne(fetch = FetchType.LAZY, mappedBy = "solicitudGUCDetalle")
        private SolicitudGUCEnvio solicitudGUCEnvio;
    
        ...
    }
    
    @Entity
    @Table(name = "TRIISOLIDGUCENV")
    public class SolicitudGUCEnvio implements Serializable {
    
        @EmbeddedId
        private SolicitudGUCId id;
    
        @OneToOne(fetch = FetchType.LAZY)
        @JoinColumns({
            @JoinColumn(name = "IDLINEA", referencedColumnName = "IDLINEA"),
            @JoinColumn(name = "IDPEDIDO", referencedColumnName = "IDPEDIDO")})
        @MapsId
        private SolicitudGUCDetalle solicitudGUCDetalle;
    
        ...
    }
    

    请注意,SolicitudGUCEnvio.solicitudGUCDetalle 使用 @MapsId@JoinColumns 进行注释(而不是 @PrimaryKeyJoinColumns)。

    在第 2.4.1 节的JPA 2.2 spec 中讨论了派生的身份(带有示例)。

    【讨论】:

    • 对不起,但在我的评论中我说这个例子是有效的。我正在尝试纠正第一个示例,它有两个不同的 EmbeddedId。谢谢。
    • @jvano 啊,我的错。您可以使用第一个示例,可能没有任何问题。但是 JPA 规范建议您将其调整为类似于我的回复中的代码:“请注意,在此示例中使用 PrimaryKeyJoinColumn 而不是 MapsId 将导致相同的映射。对于派生身份的映射,首选使用 MapsId。” [页。 38]
    【解决方案2】:

    这是我正在寻找的解决方案:

    @Embeddable
    public class SolicitudGUCDetalleId implements Serializable {
    
      @Column(name = "IDPEDIDO", insertable = false, updatable = false)
      @Size(max = 36)
      private String idPedido;
    
      @Column(name = "IDLINEA", precision = 10, scale = 0, insertable = false, updatable = false)
      private long idLinea;
    
      ...
    }
    
    @Entity
    @Table(name = "TRIISOLIDGUCDET")
    public class SolicitudGUCDetalle implements Serializable {
    
      @EmbeddedId
      private SolicitudGUCDetalleId id;
    
      @OneToOne(fetch = FetchType.LAZY, mappedBy = "solicitudGUCDetalle")
      private SolicitudGUCEnvio solicitudGUCEnvio;
    
      ...
    }
    
    @Embeddable
    public class SolicitudGUCEnvioId implements Serializable {
    
      @Column(name = "IDPEDIDO", insertable = false, updatable = false)
      @Size(max = 36)
      private String idPedido;
    
      @Column(name = "IDLINEA", insertable = false, updatable = false)
      private long idLinea;
    
      ...
    }
    
    @Entity
    @Table(name = "TRIISOLIDGUCENV")
    public class SolicitudGUCEnvio implements Serializable {
    
    
      @EmbeddedId
      private SolicitudGUCEnvioId id;
    
      @OneToOne(fetch = FetchType.LAZY)
      @JoinColumns({@JoinColumn(name = "IDLINEA", referencedColumnName = "IDLINEA"),
          @JoinColumn(name = "IDPEDIDO", referencedColumnName = "IDPEDIDO")})
      @MapsId
      private SolicitudGUCDetalle solicitudGUCDetalle;
    
      ...
    }
    

    @Brian Vosburgh,感谢您的帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-10
      • 2012-07-15
      • 2023-03-12
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      相关资源
      最近更新 更多