持久存在引用表中的@ManyToMany关系问题

时间:2013-10-14 12:21:09

标签: json hibernate jpa spring-roo spring-data-jpa

我有一个课程实体,如下所示:

@Entity
public class Curriculum {

    @ManyToMany
    private Set<Language> languages;
    ...

我正在尝试保留一个Curriculum实例,但约束是语言实例已经在数据库中

如何确保在进行持久性调用时,将一行插入curriculum表,curriculum_languages映射表但不插入 { {1}}表,因为它是一个已填充的参考表?

编辑1

- 如果我没有指定language属性,那么这是我得到的错误:

Cascade.ALL

- 如果我指定了org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.bignibou.domain.Language ,那么带有新ID的新行会被插入到Cascade.ALL表中,这显然不是我想要的......

编辑2 :请注意,我使用Spring Data JPA来保存我的实例,来自浏览器的数据是JSON对象,如下所示:

language

3 个答案:

答案 0 :(得分:0)

实现它的最简单方法可能是从数据库加载所需的语言,并在持续操作之前将它们分配给课程。

这背后的逻辑如下:

  • 当语言对象进入您的应用程序并从JSON反序列化时,它已经为其分配了一个ID字段。
  • 当您尝试持久化课程(使用从JSON反序列化的语言)时,JPA会对这些ID感到困惑,一方面它应该“了解”这些对象(ID已设置),另一方面是活动的JPA session对它们一无所知(它们来自JSON的外部世界)
  • 因此,通过ID获取语言告诉JPA谁是谁。

答案 1 :(得分:0)

当不存在的Language附带Curriculum个实例时会发生什么?是{I}}实例应该被忽略还是应该抛出Language

如果应该抛出异常,只需将实体持久化的代码包装在try-catch块中并抛出自己的异常。如果只是忽略该语言,只需在保持之前将其从Exception中删除,例如List<Language>的ID为空。

答案 2 :(得分:0)

我忘了提到我使用乐观锁定。在JSon中包含版本字段对问题进行了排序:

"languages":[{"id":46,"description":"Français","version":0}],...

如果有人愿意为此提供解释,那将会很棒......

修改:版本字段:

@Version
@Column(name = "version")
private Integer Curriculum.version;