我们有以下实体类:
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插入批次的错误切换,这导致崩溃。
这里排序前的批次顺序:(应该有效)
排序的第一步将SpawningPoint移动到Beast之后插入(这是正确的)
排序的第二步因为Fleet而使SpawningPoint失效。 Fleet在其父母身上有SpawningPoint(如上所述,这是错误的)
这会导致崩溃,因为无法在Beast之前插入SpawningPoint。
父母列表存储在GlobalUnit
:
ClassMetadata
请注意: 相同的代码在hibernate 4中运行良好,当我们转移到hibernate 5时出现问题。
如何解决问题?
TIA!
我使用了一种解决方法:GlobalUnit映射已从ClassMetadata classMetadata = action.getPersister().getClassMetadata();
Type[] propertyTypes = classMetadata.getPropertyTypes();
更改为@Entity
。在这种情况下排序工作正确,但是我们不能再使用@MappedSuperClass
来获取实体,所以我们不得不使用丑陋的开关来获取Fleet,City和SpawningPoint的实体,具体取决于对象类型,尽管在很多地方我们不需要具体的课程,session.get(GlobalUnit.class)
就足够了。