0

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

@Entity
public class Curriculum {

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

我正在尝试持久化 Curriculum 实例,但约束是 Language 实例已经在 database 中

我如何确保在调用持久化时,将一行插入到表curriculum中,curriculum_languages映射表而不是language表中,因为它是一个已经填充的引用表?

编辑1

- 如果我不指定Cascade.ALL属性,这是我得到的错误:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.bignibou.domain.Language

- 如果我确实指定了Cascade.ALL,带有新 ID 的新行将插入到language表中,这显然不是我想要的......

编辑 2:请注意,我使用 Spring Data JPA 来持久化我的实例,并且来自浏览器的数据是一个 JSON 对象,如下所示:

{"curriculum":{"languages":[{"id":46,"description":"Français"},{"id":30,"description":"Chinois"}],"firstName":"Julianito","dateOfBirth":"1975-01-06","telephoneNumber":"0608965874","workExperienceInYears":3,"maxNumberChildren":1,"drivingLicense":true}}
4

3 回答 3

0

Language当一个不存在的实例附带一个实例时会发生什么Curriculum?该Language实例应该被简单地忽略还是应该Exception被抛出?

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

于 2013-10-28T14:37:10.147 回答
0

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

这背后的逻辑如下:

  • 当一个语言对象进入您的应用程序并从 JSON 反序列化时,它已经分配了一个 ID 字段。
  • 当您尝试保留课程(使用从 JSON 反序列化的语言)时,JPA 对这些 ID 感到困惑,因为一方面它“应该”知道这些对象(设置了 ID),但另一方面活动的 JPA 会话不对他们一无所知(他们来自 JSON 的外部世界)
  • 所以通过 ID 获取语言告诉 JPA 谁是谁。
于 2013-10-28T11:43:13.010 回答
0

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

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

如果有人愿意对此提供解释,那就太好了......

编辑:版本字段:

@Version
@Column(name = "version")
private Integer Curriculum.version;
于 2013-10-28T17:00:39.843 回答