【问题标题】:How to Hibernate Annotations with circular references如何使用循环引用休眠注释
【发布时间】:2016-10-03 11:18:00
【问题描述】:

我有两个带有循环引用的表

-----------------|                   |------------------
  product        |                   | product_detail
-----------------|                   |------------------
 product_id <pk> |                   | detail_id <pk>
  ...            | <-----------------| container_id <fk>
                 | <-----------------| product_id <fk>
                 |                   | ...

我想知道怎么做属性注释

如何做@OneToMany注解

Class Product
@OneToMany ???
public List<Detail> getDetails();

如何做@ManyToOne注解

Class Detail

@ManyToOne ???
public Product getContainer();

@ManyToOne ???
public Product getProduct();

我想使用以下代码:

    Product p1 = new Product(name2);
    Product p2 = new Product(name1);

    Detail d = new Detail();

    d.setProduct(p2);

    p1.getDetails().add(d);

    ...

    Session.save(p1);

然后休眠insert into productinsert into detail

我找不到创建注释以使其正常工作的方法。你能帮帮我吗?

【问题讨论】:

  • mappedBy(在@OneToMany上)使其成为双向关系。这就是所有需要的
  • 是的,这是我在发布之前尝试过的方式,但后来我收到超时超出错误。 @OneToMany(mappedBy="container") 用于 getDetails() 列表,@ManyToOne @JoinColumn(name="container_id") 用于 getContainer()

标签: java hibernate hibernate-annotations


【解决方案1】:

在您的情况下,您的代码应如下所示:

Class Product
@OneToMany(mappedBy = "product")
public List<Detail> getDetails();

对于 Detail 类,您应该能够按原样使用 @ManyToOne 注释。所以:

Class Detail
@ManyToOne
public Product getContainer();

@ManyToOne
public Product getProduct();

这背后的原因是,在您的 @OneToMany 中,您在 mappedBy 参数中注意到 Detail 类中的哪个字段指的是 此产品。只要您遵守标准命名约定,您就不需要在 @ManyToOne 注释中提供任何额外信息。

【讨论】:

  • 使用此解决方案的详细信息对象未插入数据库,只有产品
  • 嗨 axiorema,请查看vladmihalcea.com/2015/03/05/…,然后查看一对多部分。将 cascade = CascadeType.PERSIST 添加到您的 @OneToMany 注释应该负责将孩子与您的父母一起持久化。
【解决方案2】:

我尝试了使用 mappedBy 发布的解决方案,但是当我运行示例代码时,只有产品被插入到数据库中。

我发现它工作正常的唯一方法是使用 OneToMany 侧所有者的注释:

Class Detail
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="container_id")
    public Product getContainer() {

    @ManyToOne
    @JoinColumn(name="product_id")
    public Product getProduct() {

Class Product
    @OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="container_id")
    public Set<Detail> getDetails() 

这是示例代码:

    Product p1 = new Product("the container");
    Product p2 = new Product("the product");

    Detail d = new Detail();

    d.setProduct(p2);

    p1.getDetails().add(d);

    session.save(p2);
    session.save(p1);

在这种情况下,插入了两个产品,并且也插入了详细信息。

但是有一个不方便的地方,因为如果我不想收到:

SQLIntegrityConstraintViolationException: Column 'container_id' cannot be null

我必须更改de table detail并将外键'container_id'设置为NULL,这与模型不符

CHANGE COLUMN `container_id` `container_id` INT(11) NULL 

其中一个细节必须始终有一个容器产品。

谁能解释一下这个主题?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 2015-10-25
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多