我正在使用JPA2和EclipseLink实现
![简单的表结构] [1]
以下是我尝试映射的两个表和JPA注释。
public class Story implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
Integer id;
@Temporal(TemporalType.TIMESTAMP)
@Column (name="DATE_CREATED")
Date dateCreated;
String title;
String description;
@Column(name="AUTHOR_ID")
Integer authorId;
@Column(name="COUNTRY_ID")
Integer countryId;
private String reviews;
@OneToMany(mappedBy = "story", cascade=CascadeType.ALL)
private List<Tip> tipList;
}
public class Tip implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id;
private String description;
private Integer vote;
@ManyToOne (cascade=CascadeType.ALL)
@JoinColumn(name="STORY_ID", referencedColumnName="ID")
private Story story;
}
作为一个简单的例子,我想在同一笔交易中坚持一个故事和一些故事相关的提示。 以下是执行该操作的代码部分:
Story newStory = new Story(title, body, ...);
EntityTransaction transaction = em.getTransaction().begin();
boolean completed = storyService.create(newStory);
//The tips are saved as a List<String>. This methods creates the needed List<Tip> from the Strings
List<Tip> tips = TipUtil.getTipList(tipList);
newStory.setTipList(tips)
transaction.commit();
我没有错误,所有实体都持久存储在数据库中。问题是,在提示表中,story_id
字段始终为NULL
。我可以想象JPA无法从故事表中获取新的id
。这里的正确方法是什么?
LE
在代码的当前状态中,Tip
实体是持久的,但国家/地区ID仍为空。
答案 0 :(得分:8)
使用JPA时,始终建议以双向关系更新两侧的关系。这是为了确保数据在应用程序层中保持一致,而与数据库无关。
但是,必须以双向关系更新关系的拥有方。
所以,设置/不设置
story.setTipList(tips)
取决于你。但是,如果您希望更改在DB中正确反映,那么您就可以调用
tip.setStory(story)
因为Tip
是你自己的代码所在。
你的代码看起来也不完整。理由是,
storyService.create(newStory)
返回的实体是受管理的,但不是newStory
。因此,设置newStory.setTipList(tips)
不会更新db 答案 1 :(得分:6)
因为您需要更新每个孩子的父链接故事。
完成它的方法是在Story类中创建一个addTip(Tip tip)方法。
此方法可以:
tip.setStory(this);
tipList.add(tip);
如果您不需要双向方法,可以删除提示中的故事字段,它将解决您的问题
答案 2 :(得分:1)
删除
@Column(name =“STORY_ID”) private Integer storyId;
您已在@JoinColumn中声明它(name =“STORY_ID”,referencedColumnName =“ID”)
这就是为什么你收到错误字段存在多个可写映射的原因[tip.STORY_ID]
答案 3 :(得分:0)
您不应该使用PrimaryKeyJoinColumn,只需使用JoinColumn,但是完整的课程将有助于给出一定的答案。
只有当story_id也是提示的ID(Tip中没有id)并且有一个重复的基本映射时,才会使用PrimaryKeyJoinColumn。它应该很少使用,并且在JPA 2.0中不再需要,因为不再需要重复的id映射。