我有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约束,只是为了允许记录保存而没有例外,但是除此之外,我做错了什么?
答案 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)