简体   繁体   English

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

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

The entities (using Set): 实体(使用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()

The result: 结果:

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=?

But with this entity (using List): 但是,使用此实体(使用列表):

@Entity
class Product(
    @Id
    @GeneratedValue
    val int: Int = 0,
    val name : String,
    @ManyToMany(cascade = [(CascadeType.PERSIST), (CascadeType.MERGE)])
    val stores:  MutableList<Store> = mutableListOf()
)

The result: 结果:

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 (?, ?)

From Hibernate User Guide: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many 从《 Hibernate用户指南》中: http : //docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many

When an entity is removed from the @ManyToMany collection, Hibernate simply deletes the joining record in the link table. 从@ManyToMany集合中删除实体时,Hibernate只需删除链接表中的加入记录。 Unfortunately, this operation requires removing all entries associated with a given parent and recreating the ones that are listed in the current running persistent context. 不幸的是,此操作需要删除与给定父级关联的所有条目,并重新创建当前正在运行的持久性上下文中列出的条目。

But I don't know the reason behind it, why can't we just do the same as in the Set case 但我不知道其背后的原因,为什么我们不能做到与Set情况相同

The @ManyToMany annotation with a List is telling hibernate to expect a joinTable without index 带有List的@ManyToMany注释告诉Hibernate期望没有索引的joinTable

List that don't use index column in one-to-many relation are treated implicitly as bags and this lead to 在一对多关系中不使用索引列的列表被隐式视为袋,这导致

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

Bags are the worst case. 袋子是最坏的情况。 Since a bag permits duplicate element values and has no index column, no primary key may be defined. 由于包允许重复的元素值且没有索引列,因此无法定义主键。 Hibernate has no way of distinguishing between duplicate rows. Hibernate无法区分重复的行。 Hibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. Hibernate通过完全删除(在单个DELETE中)并在集合发生更改时重新创建集合来解决此问题。

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

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