hibernate 5插入序列顺序中的错误

时间:2017-10-03 16:57:47

标签: java hibernate migration

结构

我们有以下实体类:

1:

class GlobalUnit

2:

class Fleet extends GlobalUnit

@ManyToOne
City city;

这意味着在休眠关系方面,City是Fleet的父实体,Fleet是City的子实体。

3:

class City extends GlobalUnit

4:

class SpawningPoint extends GlobalUnit

@OneToOne
Beast beast;

5:

class Beast

就休眠关系而言,Beast是产卵点的父实体,因此应该在SpawningPoint之前插入。

问题

当我们生成一个世界并将一群城市,野兽和舰队推入数据库时​​,我们会进行交易。 事务因约束违规异常而崩溃,因为:

- 在执行插入之前,hibernate对插入批次排序错误,因为:

- 在org.hibernate.engine.spi.ActionQueue类,方法sort,当{名称} if (prevBatchIdentifier.hasAnyParentEntityNames(batchIdentifier)) {且“批次标识符为true时,行Fleet会返回SpawningPoint,因为:

- hasAnyParentEntityNames检查parentEntityNames的{​​{1}},Fleet代替GlobalUnit。 (哪个错误)由于City的根实体名称为SpawningPoint,因此该方法认为SpawningPoint是他们拥有的Fleet depsite的没有任何关系,该方法返回true,这导致SpawningPoint插入批次和Fleet插入批次的错误切换,这导致崩溃。

这里排序前的批次顺序:(应该有效)

  • 0 City
  • 1 SpawningPoint
  • 2 Fleet
  • 3 Beast

排序的第一步将SpawningPoint移动到Beast之后插入(这是正确的)

  • 0 City
  • 1舰队
  • 2 Beast
  • 3 SpawningPoint

排序的第二步因为Fleet而使SpawningPoint失效。 Fleet在其父母身上有SpawningPoint(如上所述,这是错误的)

  • 0 City
  • 1 SpawningPoint
  • 2 Fleet
  • 3 Beast

这会导致崩溃,因为无法在Beast之前插入SpawningPoint。

父母列表存储在GlobalUnit

ClassMetadata

请注意: 相同的代码在hibernate 4中运行良好,当我们转移到hibernate 5时出现问题。

问题:

  1. 为什么hibernate将根实体存储在父类型中而不是参与关系的真实实体?
  2. 如何解决问题?

    TIA!

  3. 更新

    我使用了一种解决方法:GlobalUnit映射已从ClassMetadata classMetadata = action.getPersister().getClassMetadata(); Type[] propertyTypes = classMetadata.getPropertyTypes(); 更改为@Entity。在这种情况下排序工作正确,但是我们不能再使用@MappedSuperClass来获取实体,所以我们不得不使用丑陋的开关来获取Fleet,City和SpawningPoint的实体,具体取决于对象类型,尽管在很多地方我们不需要具体的课程,session.get(GlobalUnit.class)就足够了。

0 个答案:

没有答案