【问题标题】:OneToOne with composite PK with columns from related tablesOneToOne 与复合 PK 与相关表中的列
【发布时间】:2020-03-17 11:42:03
【问题描述】:

我有三张桌子,比如说 A、B 和 C:

Table A
id
country
B_id

Table B
id
name

Table C
country
name
description

表 C 有一个由列组成的复合 PK:countryname

现在我想建立一个从表 A 的实体到表 C 的实体的 OneToOne 连接。

实体 C:

@Table(name = "C")
public class C {

    @EmbeddedId
    private CountryName id;
    @Column(nullable = false)
    private String description;
...
}

在实体 A 中,我正在尝试这样的事情:

@Table(name = "A")
public class A {

    @Id
    @Type(type = "pg-uuid")
    private UUID id;

    @Column(nullable = false)
    private String country;    

    @JoinColumn(updatable = false, insertable = false)
    private B b;

    @OneToOne(optional = false)
    @JoinColumns({
          @JoinColumn(name = "country"),
          @JoinColumn(name = "B.name")
    private C c;

B 表的name 列的引用不起作用。你能帮忙知道如何实现这一点吗?

【问题讨论】:

  • 让我明白:A.country == C.country && A.country == B.name ?

标签: java postgresql hibernate jpa spring-data-jpa


【解决方案1】:

我认为@JoinColumns应该在C类中,A类可以使用mappedBy元素:

@Table(name = "A")
public class A {
    @OneToOne(optional = false, mappedBy = "id")
    private C c;
}
@Table(name = "C")
public class C {
    @EmbeddedId
    @JoinColumns({
        @JoinColumn(name = "id.country"),
        @JoinColumn(name = "id.name")
    })
    private CountryName id;
}

【讨论】:

    【解决方案2】:
    @Table(name = "A")
    public class A {
    
        @Id
        @Type(type = "pg-uuid")
        private UUID id;
    
        @Column(nullable = false)
        private String country;    
    
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name= "B_id", referencedColumnName = "id",updatable = false, insertable = false)
        private B b;
    
        @OneToOne(optional = false)
        @JoinColumns({
              @JoinColumn(name = "country"),
              @JoinColumn(name = "B.name")
        private C c;
    

    如果你想双向进行,还可以添加:

    @Table(name = "C")
    public class C {
    
        @EmbeddedId
        private CountryName id;
        @Column(nullable = false)
        private String description;
    
        @OneToOne(mappedBy = "c")
        private A a;
    
    }
    

    【讨论】:

      【解决方案3】:

      使用以下映射:

      @Entity
      public class A {
      
          @Id
          @GeneratedValue
          private Long id;
      
          @Column(nullable = false)
          private String country;
      
          @OneToOne
          @JoinColumnOrFormula(column = @JoinColumn(name = "country", referencedColumnName = "country", insertable = false, updatable = false))
          @JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "name", value = "(SELECT bTable.name FROM B bTable WHERE bTable.id = id)"))
          private C c;
      }
      
      @Entity
      public class B implements Serializable {
      
          @Id
          @OneToOne
          @JoinColumn(name = "id")
          private A1 a;
      
          private String name;
      }
      
      @Entity
      public class C {
      
          @EmbeddedId
          private CountryName id;
      
          @Column(nullable = false)
          private String description;
      }
      
      @Embeddable
      public class CountryName implements Serializable {
      
          private String country;
          private String name;
      }
      

      以下代码:

      A a = new A();
      B b = new B();
      b.setA(a);
      b.setName("United Kingdom");
      C c = new C();
      CountryName id = new CountryName();
      id.setCountry("UK");
      id.setName("United Kingdom");
      c.setId(id);
      c.setDescription("Dieu et mon droit");
      a.setCountry("UK");
      em.persist(a);
      em.persist(b);
      em.persist(c);
      em.flush();
      em.clear();
      A retrieved = em.find(A.class, a.getId());
      System.out.println(retrieved.getC().getDescription());
      

      打印“Dieu et mon droit”。这或多或少是您想要的吗?

      没有 Hibernate 的 @JoinFormula 就无法实现连接。 JPA 要求 @JoinColumns.value() 中的所有连接列都驻留在同一个表中。

      【讨论】:

        猜你喜欢
        • 2015-06-17
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多