具有反向外键的单向@OneToOne

时间:2015-06-15 17:43:39

标签: hibernate jpa jpa-2.0

我们希望使用不在主表中但在从站中的外键创建单向@OneToOne映射。通过提供以下Java代码,Hibernate尝试在表product_ID中查找列product,但不在productimage中查找。是否可以使其仅对注释进行修改?

从示例中删除了所有不必要的字段和列。

JPA实体:

@Entity
public class Product {

    @Id
    @Column(name = "ID", unique = true)
    private String id;

    // this doesn't work
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "product_ID", nullable = false)
    private ProductImage productImage;

    // this works, but we want one-to-one
    // @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    // @JoinColumn(name = "product_ID", nullable = false)
    // private List<ProductImage> productImages;

    // getters/setters omitted
}

@Entity
public class ProductImage {

    @Id
    @Column(name = "ID", unique = true)
    private String id;

    @Column
    @Lob
    private Blob data;

    // getters/setters omitted
}

数据库表:

CREATE TABLE `product` (
  `ID` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`)
)

CREATE TABLE `productimage` (
  `ID` varchar(255) NOT NULL,
  `data` longblob NOT NULL,
  `product_ID` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `FK_123` (`product_ID`),
  CONSTRAINT `FK_123` FOREIGN KEY (`product_ID`) REFERENCES `product` (`ID`)
)

4 个答案:

答案 0 :(得分:1)

@OneToOne有点误导。它很可能与您想要的不同。在大多数情况下,经典数据库“一对一”关系通过@ManyToOne JPA注释建模。试试吧。通过@ManyToOne和@JoinColumn从未遇到过单向关系的问题。我还在第二节中明确指定了productId字段。

答案 1 :(得分:1)

JPA实体,更多关于@PrimaryKeyJoinColumn

@Entity
public class Product {
    @Id
    private String id;

    @PrimaryKeyJoinColumn
    @OneToOne(orhanRemoval = true)
    private ProductImage image;
}

@Entity
public class ProductImage {
    @Id
    private String productId; // this will be foreign key as well as primary

   //other properties goes here
}

数据库表:

CREATE TABLE product (
    id VARCHAR PRIMARY KEY
);

CREATE TABLE product_image (
    product_id VARCHAR PRIMARY KEY REFERENCES product(id)
    -- other columns goes here
);

答案 2 :(得分:0)

无论您将其映射为@OneToOne还是@OneToMany,实际上既不在这里也不在那里:客户端只能使用您公开的内容,因此将其映射为@OneToMany并隐藏实现。

@Entity
public class Product {

    @Id
    @Column(name = "ID", unique = true)
    private String id;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "product_ID", nullable = false)
    private List<ProductImage> productImages;

    //no getters or setters for productImages;

    public ProductImage getProductImage(){
         return productImages.size() > 0 ? productImages.get(0) : null;
    }
}

我也没有看到将关系双向化为1-2-1或1-2-M的任何特殊问题。同样,不要从ProductImage&gt;中公开引用。产品,如果您不希望公开发布。

答案 3 :(得分:0)

这是一对一的逆关系。在正常(非反向)关系中,源对象保留指向目标对象的指针(表中的列)。但是在相反的情况下,目标对象具有指向源对象的指针。

因此,您需要使用 rQ01 = (q.Q1 == true) ? "Yes" : "No", rQ02 = (q.Q2 == true) ? "Yes" : "No", rQ03 = (q.Q3 == true) ? "Yes" : "No", rQ04 = (q.Q4 == true) ? "Yes" : "No", rQ05 = (q.Q5 == true) ? "Yes" : "No", rQ06 = (q.Q6 == true) ? "Yes" : "No", rQ07 = (q.Q7 == true) ? "Yes" : "No", rQ08 = (q.Q8 == true) ? "Yes" : "No", rQ09 = (q.Q9 == true) ? "Yes" : "No", rQ10 = (q.Q10 == true) ? "Yes" : "No", rQ11 = (q.Q11 == true) ? "Yes" : "No", rQ12 = (q.Q12 == true) ? "Yes" : "No", rQ13 = (q.Q13 == true) ? "Yes" : "No", rQ14 = (q.Q14 == true) ? "Yes" : "No", rQ15 = (q.Q15 == true) ? "Yes" : "No", rQ16 = (q.Q16 == true) ? "Yes" : "No", rQ17 = (q.Q17 == true) ? "Yes" : "No", rQ18 = (q.Q18 == true) ? "Yes" : "No", rQ19 = (q.Q19 == true) ? "Yes" : "No", rQ20 = (q.Q20 == true) ? "Yes" : "No", rQ21 = (q.Q21 == true) ? "Yes" : "No", rQ22 = (q.Q22 == true) ? "Yes" : "No", rQ23 = (q.Q23 == true) ? "Yes" : "No", rQ24 = (q.Q24 == true) ? "Yes" : "No", rQ25 = (q.Q25 == true) ? "Yes" : "No", rQ26 = (q.Q26 == true) ? "Yes" : "No", rQ27 = (q.Q27 == true) ? "Yes" : "No", rQ28 = (q.Q28 == true) ? "Yes" : "No", rQ29 = (q.Q29 == true) ? "Yes" : "No" 属性来告知该关系的键在另一端。

在您的情况下,您需要在目标实体侧引入mappedBy注释:

@OneToOne