@ManyToOne映射无法保存父ID

时间:2012-02-28 10:50:21

标签: java jpa entity-relationship

我正在使用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仍为空。

4 个答案:

答案 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映射。