hibernate - Hibernate bi-directional @ManyToAny mapping
问题描述
I have two entities ProductEntity
and CategoryEntity
and they both have a many-to-many relationship. It all works fine - I can call product.getCategories()
and category.getProducts()
and it returns correctly. And more importantly I can add a Category
to a Product
and a Product
to a Category
and then save them and it all works fine.
Now I want to add a new entity DocumentEntity
that also has a collection of CategoryEntity
. For that reason I introduce a parent entity called AbstractCategorizableEntity
and have both ProductEntity
and CategoryEntity
to extend from it.
Then the mapping becomes like this:
public class CategoryEntity {
@JoinTable(name = "categorizable_category", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "categorizable_id"))
@ManyToAny(fetch = FetchType.LAZY, metaDef = AbstractCategorizableEntity.META_DEF_NAME, metaColumn = @Column(name = "categorizable_type"))
private Set<AbstractCategorizableEntity> categorizables;
}
public class AbstractCategorizableEntity {
@JoinTable(name = "categorizable_category", joinColumns = @JoinColumn(name = "categorizable_id"), inverseJoinColumns = @JoinColumn(name = "category_id"))
@ManyToMany(fetch = FetchType.LAZY, targetEntity = CategoryEntity.class, cascade = { CascadeType.MERGE })
private Set<CategoryEntity> categories;
}
Now reading works fine. Also writing works fine when writing from the category side:
CategoryEntity category = new CategoryEntity();
category.setCategorizables(Sets.newHashSet(product, document));
entityManager.persist(category); // <---- WORKS FINE
However if I try to save the product and set the category I get an exception:
ProductEntity product = new ProductEntity();
product.setCategories(Sets.newHashSet(category1));
entityManager.persist(product); //<----- EXCEPTION HAPPENS
I get an exception that
2020-12-03 22:43:22,524 [main] ERROR: Referential integrity constraint violation: "FK1LY02CXDDJEEXOA2WQL85NTAW: PUBLIC.ABSTRACT_CATEGORIZABLE_PRODUCT FOREIGN KEY(ABSTRACT_CATEGORIZABLE_ID) REFERENCES PUBLIC.PRODUCT(ID) (142152297423644336)"; SQL statement:
insert into categorizable_category (abstract_categorizable_id, category_id) values (?, ?) [23506-200]
It seems that it cannot save it because I am not passing the metaColumn
.
My questions is: how can I map a many-to-many relation with polymorphic entities? How can I pass the meta-column when saving the product?
解决方案
You have 3 options:
- Use SINGLE_TABLE or JOINED inheritance for
AbstractCategorizableEntity
- Disable the foreign key generation
- Just declare abstract getters and setter in
AbstractCategorizableEntity
and use dedicated join tables for every subtype forcategories
推荐阅读
- javascript - ServiceWorker / 缓存 / 设置 TTL
- r - rpart 警告消息,然后没有形成适当的 rpart 图
- javascript - 如何在javascript中将缓冲区转换为图像src
- jsf - 从 FacesContext 设置时,焦点在 Chrome 中不起作用
- python - 在 step 函数中获取 AWS 状态机执行 ARN
- r - 使用cowplot 拼凑图时颜色渐变不正确
- r - 分组并计算从 t-1 年到 t 年的文本数据的余弦相似度?
- bash - SHELL - IF 语句中的 AND 操作
- python - 气流网络服务器已启动,但 UI 未在浏览器中显示
- c# - TimeZoneInfo.ConvertTimeFromUtc 未在已部署的 Azure Webjob 上正确应用 DST