繁体   English   中英

为什么使用List时Hibernate需要在单向ManyToMany中重新创建其他条目

[英]Why Hibernate need to recreate other entries in unidirectional ManyToMany when using List

实体(使用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=?

但是,使用此实体(使用列表):

@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情况相同

带有List的@ManyToMany注释告诉Hibernate期望没有索引的joinTable

在一对多关系中不使用索引列的列表被隐式视为袋,这导致

https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/performance-collections.html

袋子是最坏的情况。 由于包允许重复的元素值且没有索引列,因此无法定义主键。 Hibernate无法区分重复的行。 Hibernate通过完全删除(在单个DELETE中)并在集合发生更改时重新创建集合来解决此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM