实体(使用Set):
@Entity
class Product(
@Id
@GeneratedValue
val int: Int = 0,
val name : String,
@ManyToMany(cascade = [(CascadeType.PERSIST), (CascadeType.MERGE)])
val stores: MutableSet<Store> = mutableSetOf()
)
@Entity
class Store(
@Id
@GeneratedValue
val int: Int = 0,
val name : String = ""
)
...
val p = Product(name = "product")
em.persist(p)
val store = Store(name = "store");
p.stores += store
em.persist(store)
for (i in 1..5) {
val s = Store(name = i.toString())
p.stores += s
em.persist(s)
}
em.flush()
p.stores.remove(store)
em.flush()
结果:
Hibernate: insert into product (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: delete from product_stores where product_int=? and stores_int=?
但是使用这个实体(使用List):
@Entity
class Product(
@Id
@GeneratedValue
val int: Int = 0,
val name : String,
@ManyToMany(cascade = [(CascadeType.PERSIST), (CascadeType.MERGE)])
val stores: MutableList<Store> = mutableListOf()
)
结果:
Hibernate: insert into product (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into store (name, int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: delete from product_stores where product_int=?
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
Hibernate: insert into product_stores (product_int, stores_int) values (?, ?)
来自Hibernate用户指南: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many
当从@ManyToMany集合中删除实体时,Hibernate只删除链接表中的连接记录。不幸的是,此操作需要删除与给定父级关联的所有条目,并重新创建当前运行的持久化上下文中列出的条目。
但我不知道其背后的原因,为什么我们不能像Set案例一样做
答案 0 :(得分:1)
答案 1 :(得分:1)
带有List的@ManyToMany注释告诉hibernate期望没有索引的joinTable
在一对多关系中不使用索引列的列表被隐式处理为包,这导致
https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/performance-collections.html
袋子是最糟糕的情况。由于包允许重复的元素值并且没有索引列,因此不能定义主键。 Hibernate无法区分重复的行。 Hibernate通过完全删除(在单个DELETE中)并在每次更改时重新创建集合来解决此问题。