为什么Hibernate的cascadtype属性只适用于对象的子对象而不适用于子对象的子对象? &g



我在Java应用程序中使用Hibernate,我注意到cascadtype属性似乎只适用于对象的直接子对象,而不适用于子对象的子对象。

例如,假设我有一个Product具有TextContent对象作为其字段之一。如果我将Customer字段中的cascadtype属性设置为ALL,则对Product所做的任何更改对象将自动持久化,当TextContent对象被持久化。

但是TextContent有一个列表翻译对象作为它的一个字段,并且我将翻译字段的cascadtype属性设置为ALL,对TextContent所做的更改对象将不会自动持久化,当翻译对象被持久化(翻译中的FK是NULL而不是TextContent的id)。

为什么会这样?是否有一种方法,使cascadtype属性工作的孩子的孩子,以及?

实体:

public class Product {
private Integer id;
@ManyToOne(cascade = CascadeType.ALL)
public TextContent textContentName;
}
public class TextContent {
private Integer id;
@OneToMany(mappedBy = "textContent", cascade = CascadeType.ALL)
private List<Translation> translations;
}
public class Translation {
private Integer id;
private String translation;
@ManyToOne()
private Language language;
@JsonIgnore()
@ManyToOne()
private TextContent textContent;
}
public class Language {
private Integer id;

private String acronym;
}

发送到控制器的产品JSON:

{
"id": null,
"textContentName": {
"id": null,
"translations": [
{
"id": null,
"translation": "Product name in English",
"language":{
"id": 1,
"acronym": "en"
}
},
{
"id": null,
"translation": "Nombre del producto en Español",
"language":{
"id": 2,
"acronym": "es"
}
}
]
}
}

JPA控制器的执行:

productRepository.save(product)

域模型中的关联表示不同的域实体如何相互关联。通常这些关系可以表示为亲子关系。

Cascade作用于父表和子表中使用f.k key直接相关的记录。

因为Hibernate JPA将引用完整性问题委托给底层SQL数据库的外键约束。

这个设计决策有一个很好的理由。因为可以在关联级别控制分离对象的合并。

所以只有那些与你的父实体关联的子实体得到级联,而不是子实体的子实体。

我认为你不了解CascadeType是做什么的。

  1. 不是关于与数据库同步更改(更新)。[默认情况下]对实体的更改会在刷新时自动检测并同步到数据库,只要在刷新持久性上下文时该实体与持久性上下文相关联。
  2. 级联就是对persist()merge()refresh()remove()显式操作进行级联,绝对是递归的。

我不能确切地指出你的困惑/问题的根源,因为你没有给我们看任何代码。

由于某些原因,hibernate需要引用TextContent对象在翻译对象,即使该引用可以从Translation的子对象推导出来(TextContent) .

我设法通过修改Translations的setter来解决它。TextContent列表传递自:

的实体
public class TextContent {
private Integer id;
@OneToMany(mappedBy = "textContent", cascade = CascadeType.ALL)
private List<Translation> translations;
public setTranslations(List<Translation> translations){
this.translations = translations;
}
}

:

public class TextContent {
private Integer id;
@OneToMany(mappedBy = "textContent", cascade = CascadeType.ALL)
private List<Translation> translations;
public setTranslations(List<Translation> translations){
translations.forEach((translation) => {
translation.setTextContent(this);
});
this.translations = translations;
}
}

在调用产品的save()方法时这样做会创建TextContent对象和翻译与相同的TextContent相关联,

相关内容

  • 没有找到相关文章

最新更新