@ManyToOne映射无法保存父 ID

2022-09-03 14:10:19

我正在使用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();

我没有错误,所有实体都保留在数据库中。问题是,在提示表中,字段始终为 。我可以想象JPA无法从故事表中获取新的内容。这里的正确方法是什么?story_idNULLid

在代码的当前状态下,实体将持久化,但国家/地区 ID 仍为 null。Tip


答案 1

使用 JPA 时,始终建议在双向关系中更新双方的关系。这是为了确保数据在应用程序层中是一致的,并且与数据库无关。

但是,您必须在双向关系中更新关系的拥有方。

因此,设置/不设置

story.setTipList(tips)

由你决定。但是,如果您希望更改在 DB 中正确反映,那么您可以调用

tip.setStory(story)

就像这里的所有权一样,按照你的代码。另外,你的代码对我来说看起来不完整。原因是,Tip

  • 返回的实体是托管的,但不是 .所以只是设置不会更新数据库storyService.create(newStory)newStorynewStory.setTipList(tips)

答案 2

因为您需要更新每个孩子的父链接故事。

完成它的方式是在 Story 类中创建一个 addTip(Tip tip) 方法。

此方法执行:

tip.setStory(this);
tipList.add(tip);

如果您不需要定向方法,则可以删除Tip中的故事字段,它将解决您的问题


推荐