也许这是一个容易回答的问题......但我没有让它运行。在persist()中,我得到了子表中的引用键为null的异常(数据库当然不允许这样做)。我有一个配方和一些准备步骤。
我正在使用EclipseLink 2.4.1
Recipe.java(rcpid由JPA自动设置)
@Entity
public class Recipe {
@Id
long rcpid;
List<Recipestep> recipesteps = new ArrayList<>();
@OneToMany(
cascade=CascadeType.ALL,
fetch=FetchType.EAGER,
mappedBy="recipe",
targetEntity=Recipestep.class )
// This does NOT work. Following line tries to access a join-table !!!
// @JoinColumn(name="rcpid", referencedColumnName="rcpid")
public List<Recipestep> getRecipesteps() { return recipesteps; }
// some more attributes, getters and setters
}
Recipestep.java(rpsid由JPA自动设置)
@Entity
public class Recipestep {
@Id
long rpsid;
Recipe recipe;
@ManyToOne( targetEntity=Recipe.class )
@JoinColumn( name="rcpid" )
public Recipe getRecipe() { return recipe; }
// some more attributes, getters and setters
}
上面的代码是一种有效的解决方法。但是,为了获得干净(且可支持)的代码,关系应该只与父级中引用其所有子代的集合的单向关系。
答案 0 :(得分:1)
您已将此映射为单向多对多,但对recipestep rcpid数据库列有两个映射。尝试将long rcpid更改为
@ManyTOne
Recipe rcp;
然后从oneToMany中删除joincolumn定义,并通过将其标记为rcp manyToOne关系映射使其成为双向。这里发布了一个示例http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Relationship_Mappings/Collection_Mappings/OneToMany
首次插入目标实体时,Eclipselink将始终使用joincolumn在单向oneToMany关系上插入空值,然后在处理Recipe实体时更新它。 Recipestep中的rcpid映射也可能为null,这意味着您对同一个字段有两个可写映射,特别是当它们发生冲突时会出现问题。
答案 1 :(得分:0)
您遇到了默认的JPA行为。将实体添加到recipesteps
列表不足以创建双向关系。
要解决此问题,您需要在列表中的每个元素上明确设置rcpid
。
编辑:我认为问题是JPA不知道在Recipestep表中存储Recipe
的id的位置。它假设一个名称(“recipebo_rcpid”),但你的表似乎缺少它。
尝试将“recipe_id”列添加到Recipestep
表,并将mappedBy
属性添加到@OneToMany
注释:
@OneToMany(
cascade=CascadeType.ALL,
fetch = FetchType.EAGER,
mappedBy = "recipe" )
您可能不需要注释中的targetEntity
属性 - List
已经输入。