Java: 保存具有 ManyToMany 关联的实体
Java: saving entities with ManyToMany association
我在保存具有多对多关联的实体时遇到问题。我已经阅读了一些关于此的帖子,但没有得出结论。
我有两个与 ManyToMany 关联的实体。我读过创建此实体的正确方法是在它们之间创建关联而不是创建第三个实体来保存关联,因此我以这种方式实现了它。当我 运行 代码时,它会按预期创建第三个 FK table,但是当我尝试使用此关联保存新对象时,会发生以下两种情况之一:
- 在第一个示例中,我首先创建了 RawMaterial 实体,然后创建了 Product 实体。此操作 returns 错误:org.hibernate.PersistentObjectException:分离的实体传递给持久化;
- 第二个例子,我先创建Product实体。然后我创建 RawMaterial 实体并保存它。它成功地在数据库上创建了两条线,但没有在 FK table.
上创建任何关联
我的代码是:
产品实体:
@Entity
@Table(name = "products")
public class Product {
//Product attributes
...
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "product_raw_material",
joinColumns = @JoinColumn(name = "raw_material_id"),
inverseJoinColumns = @JoinColumn(name = "product_id"))
private Set<RawMaterial> rawMaterialList = new HashSet<>();
//Getters and setters
}
原材料实体:
@Entity
@Table(name = "raw_materials",
uniqueConstraints = {@UniqueConstraint(columnNames =
{"bar_code"}),
@UniqueConstraint(columnNames = {"name"})})
public class RawMaterial {
//RawMaterial attributes
...
@ManyToMany(mappedBy = "rawMaterialList")
private Set<Product> productsList = new HashSet<>();
//Getters and setters
}
首次尝试创建新的 Product 和 RawMaterial 实体:
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
Set<RawMaterial> materialsList = new HashSet<>();
RawMaterial savedMaterial = rawMaterialRepository.save(material);
materialsList.add(savedMaterial);
Product product = new Product("code", "name", materialsList,
LocalDateTime.now(), LocalDateTime.now());
Product savedProduct = productRepository.save(product);
此示例 returns 尝试保留产品实体时的错误: org.hibernate.PersistentObjectException:已分离的实体传递给保留。
第二次尝试:
Product product = new Product("code", "name", null,
LocalDateTime.now(),
LocalDateTime.now());
Product savedProduct = productRepository.save(product);
Set<Product> productsSet = new HashSet<>();
productsSet.add(savedProduct);
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
material.getProductsList().add(productsSet.stream()
.iterator().next());
rawMaterialRapository.save(material);
这会在每个 table 上创建一个新条目,但不会在关联 table 上创建任何内容(自动生成的 product_raw_material 关联 table)。
我不知道是否应该指定一个实体来保存关联,或者我是否在存储库中遗漏了某些内容。感谢您的帮助。
试试这个
@Transactional
public Product saveProduct() {
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
Set<RawMaterial> materialsList = new HashSet<>();
materialsList.add(material);
Product product = new Product("code", "name", materialsList,
LocalDateTime.now(), LocalDateTime.now());
material.getProductsList().add(product);
return productRepository.save(product);
}
在您的设计中,关联的所有者是 RawMaterial
因为您使用 mappedBy
属性作为 RawMaterial。这很好,但是当你想保留 RawMaterial 时,它会尝试执行负责的事情(创建 product_raw_material 并插入带有关联方 FK 的行)但是没有可以使用的 Product 记录。这就是为什么您会收到您描述的错误。
我在保存具有多对多关联的实体时遇到问题。我已经阅读了一些关于此的帖子,但没有得出结论。 我有两个与 ManyToMany 关联的实体。我读过创建此实体的正确方法是在它们之间创建关联而不是创建第三个实体来保存关联,因此我以这种方式实现了它。当我 运行 代码时,它会按预期创建第三个 FK table,但是当我尝试使用此关联保存新对象时,会发生以下两种情况之一:
- 在第一个示例中,我首先创建了 RawMaterial 实体,然后创建了 Product 实体。此操作 returns 错误:org.hibernate.PersistentObjectException:分离的实体传递给持久化;
- 第二个例子,我先创建Product实体。然后我创建 RawMaterial 实体并保存它。它成功地在数据库上创建了两条线,但没有在 FK table. 上创建任何关联
我的代码是:
产品实体:
@Entity
@Table(name = "products")
public class Product {
//Product attributes
...
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "product_raw_material",
joinColumns = @JoinColumn(name = "raw_material_id"),
inverseJoinColumns = @JoinColumn(name = "product_id"))
private Set<RawMaterial> rawMaterialList = new HashSet<>();
//Getters and setters
}
原材料实体:
@Entity
@Table(name = "raw_materials",
uniqueConstraints = {@UniqueConstraint(columnNames =
{"bar_code"}),
@UniqueConstraint(columnNames = {"name"})})
public class RawMaterial {
//RawMaterial attributes
...
@ManyToMany(mappedBy = "rawMaterialList")
private Set<Product> productsList = new HashSet<>();
//Getters and setters
}
首次尝试创建新的 Product 和 RawMaterial 实体:
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
Set<RawMaterial> materialsList = new HashSet<>();
RawMaterial savedMaterial = rawMaterialRepository.save(material);
materialsList.add(savedMaterial);
Product product = new Product("code", "name", materialsList,
LocalDateTime.now(), LocalDateTime.now());
Product savedProduct = productRepository.save(product);
此示例 returns 尝试保留产品实体时的错误: org.hibernate.PersistentObjectException:已分离的实体传递给保留。
第二次尝试:
Product product = new Product("code", "name", null,
LocalDateTime.now(),
LocalDateTime.now());
Product savedProduct = productRepository.save(product);
Set<Product> productsSet = new HashSet<>();
productsSet.add(savedProduct);
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
material.getProductsList().add(productsSet.stream()
.iterator().next());
rawMaterialRapository.save(material);
这会在每个 table 上创建一个新条目,但不会在关联 table 上创建任何内容(自动生成的 product_raw_material 关联 table)。
我不知道是否应该指定一个实体来保存关联,或者我是否在存储库中遗漏了某些内容。感谢您的帮助。
试试这个
@Transactional
public Product saveProduct() {
RawMaterial material = new RawMaterial("barcode", "name",
LocalDateTime.now(),
LocalDateTime.now());
Set<RawMaterial> materialsList = new HashSet<>();
materialsList.add(material);
Product product = new Product("code", "name", materialsList,
LocalDateTime.now(), LocalDateTime.now());
material.getProductsList().add(product);
return productRepository.save(product);
}
在您的设计中,关联的所有者是 RawMaterial
因为您使用 mappedBy
属性作为 RawMaterial。这很好,但是当你想保留 RawMaterial 时,它会尝试执行负责的事情(创建 product_raw_material 并插入带有关联方 FK 的行)但是没有可以使用的 Product 记录。这就是为什么您会收到您描述的错误。