【问题标题】:Entity manager changes detached entities实体管理器更改分离的实体
【发布时间】:2020-07-30 03:59:14
【问题描述】:

帮帮我。

为什么交易后实体中的集合会发生变化?

我的实体:

@Entity
class Entity(
  @Id
  val uuid: UUID,

  @OneToMany(cascade = [CascadeType.PERSIST, CascadeType.REMOVE])
  @JoinTable(
    name = "entities_items",
    joinColumns = [JoinColumn(name = "entity_uuid")],
    inverseJoinColumns = [JoinColumn(name = "item_uuid")]
  )
  val items: MutableList<Item>
) 

我的测试:

@SpringBootTest
internal class EntityTest {
  @Autowired
  lateinit var entityRepository: EntityRepository

  @Autowired
  lateinit var transactionManager: PlatformTransactionManager

  @Test
  fun will_added_item() {
    val entityBefore = entityRepository.findById(entityId).get()
    // entityBefore.items.size == 0

    TransactionTemplate(transactionManager).execute { _ ->
      val entity = entityRepository.findById(entityId).get()

      entity.items.add(item)
    }

    // entityBefore.items.size == 1 <-- ???
    val entityAfter = entityRepository.findById(entityId).get()
  }
}

有趣的是,如果我在事务之前添加任何对集合的调用,一切都会好起来的。

Spring Boot + Hibernate + JUnit

【问题讨论】:

标签: spring jpa testing kotlin entitymanager


【解决方案1】:
  • 请忽略这个错误答案 - 在我的手机上似乎无法删除它!

这是因为当您在事务中多次按 id 检索项目时,Hibernate 会为您提供相同的对象,因为它将事务中涉及的对象作为工作单元进行管理。

因此 entityBefore 和 entity 指向同一个对象。

抱歉,忽略 - 我看到第一次检索在 tx 之外!

【讨论】:

  • 有趣的是,如果我在事务之前向集合添加任何调用,一切都会好起来的。
  • 嗯 - 很有趣,将对此进行快速阅读。大概在测试中 entityBefore 和 entity 指向同一个对象,但这只是奇怪的行为 - 虽然不是我第一次在 Hibernate 中遇到奇怪的东西
  • 嗯......更多奇怪的东西!如果在调试模式下在事务之前停止执行并继续,一切都会好起来的。
  • 只看 Persistence Bag,这是 Hibernate 用它自己的集合类型替换你的集合类型的不直观的事情 - 在最近的一个问题中出现,其中有人有一个 Sorted 集合类型但有点抛出,因为 Hibernate 使用了一个未排序的集合。没有解释为什么 Hibernate 似乎以与内部相同的单位管理事务外部的实体
  • Persistence Bag 只是一个假设。我不知道为什么会这样 :( 毕竟每个事务都有自己的持久化上下文。这意味着所有特殊类型都不应该影响外部代码。
猜你喜欢
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2010-10-02
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多