Hibernate不会在插入

时间:2017-02-21 00:35:23

标签: java mysql hibernate jpa

我有3个具有层次关系的表:

页面(祖母)

    public class Page extends BaseDAO {

      @Id
      @GeneratedValue(strategy = IDENTITY)
      @Column(name = "page_id", unique = true, nullable = false)
      public Integer getPageId() {
        return this.pageId;
      }

      @OneToMany(fetch = FetchType.EAGER, mappedBy = "page", cascade=CascadeType.ALL, orphanRemoval=true)
      @NotFound(action = NotFoundAction.IGNORE)
      public Set<PageWell> getPageWells() {
        return this.pageWells;
      }
    }

PageWell (母亲)

    public class PageWell extends BaseDAO {
        @Id
        @Column(name = "page_well_id", unique = true, nullable = false)
        public int getPageWellId() {
           return this.pageWellId;
        }

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "page_id", nullable = false)
        public Page getPage() {
            return this.page;
        }

        @OneToMany(fetch = FetchType.EAGER, mappedBy = "pageWell", cascade=CascadeType.ALL)
        public Set<PageComponentAttribute> getPageComponentAttributes() {
            return this.pageComponentAttributes;
        }
    }

PageComponentAttribute (女儿)

    public class PageComponentAttribute extends BaseDAO {
        @Id
        @GeneratedValue(strategy = IDENTITY)
        @Column(name = "page_component_attribute_id", unique = true, nullable = false)
        public Integer getPageComponentAttributeId() {
           return this.pageComponentAttributeId;
        }

        @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
        @JoinColumn(name = "page_well_id", nullable = false)
        public PageWell getPageWell() {
            return this.pageWell;
        }
    }

所有三个表的主键都是MySQL中的AutoIncrement。预期的行为是,当我保存页面时,将保存所有 PageWell 对象,并且还会保存所有 PageComponentAttribute 对象。

出于某种原因,它对Grandmonther正常工作 - &gt;女儿的关系。但在母亲的情况下 - &gt;女儿关系,女儿的外键每次都设为0。这显然会导致违反约束。我暂时删除了该关系的FK约束,并且记录进入表中,但FK仍为0.

我的保存代码如下所示:

    Page page = getPage(request);  //getPage() finds an instance of page, or creates and persists a new instance if none exists.
    Set<PageWell> wells = page.getPageWells();
    wells.clear();  //delete all related PageWell objects so we can re-create them from scratch

    page = pageHome.merge(page);
    wells = page.getPageWells();
    PageWell pageWell;

    // Now create a new PageWell and set up bi-directonal mapping with Page.  This part works great.
    pageWell = new PageWell();
    pageWell.setPage(page);
    wells.add(pageWell);

    // Now do the exact same thing with the PageComponentAttribute objects
    PageComponentAttribute pca = new PageComponentAttribute();
    pca.setPageWell(pageWell);
    pca.getPageWell().getPageComponentAttributes().add(pca);

    // Now save the Page
    page = pageHome.merge(page);

当我检查数据库时, PageComponentAttribute 表中的FK被设置为0.同样,我暂时从MySQL中删除了FK约束,只是为了允许记录保存而没有例外,但是除此之外,我做错了什么?

2 个答案:

答案 0 :(得分:2)

我会尝试做其中的一件事,或全部:

1)从@ManyToOne中删除级联。一般而言,将其配置为不是一个好主意。它基本上只对@OneToMany和@OneToOne有意义。

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "page_well_id", nullable = false)
public PageWell getPageWell() {
    return this.pageWell;
}

2)尝试使用Hibernate级联配置而不是JPA:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "pageWell")
@Cascade(CascadeType.ALL)
public Set<PageComponentAttribute> getPageComponentAttributes() {
       return this.pageComponentAttributes;
}

可能会有一些小差异,请参阅:article

3)不确定为什么要在merge实体上两次调用page。我会在最后坚持一个。

4)我想到的最后一个解决方法是在这里执行显式刷新:

pageWell = new PageWell();
pageWell.setPage(page);
wells.add(pageWell);
session.flush();

然后:

PageComponentAttribute pca = new PageComponentAttribute();
pca.setPageWell(pageWell);
pca.getPageWell().getPageComponentAttributes().add(pca);

session.merge(pageWell);

理论上,pageWell应该已经生成了主要因为刷新而且它不应该再为0。

我希望我现在有一个测试环境来正确测试它。

答案 1 :(得分:0)

如果有人犯了同样的骨头错误,问题就在于,PageWell实体的主键没有生成策略。我补充说,它解决了我的问题。

    @GeneratedValue(strategy = IDENTITY)