AnotherDependentEntity

AnotherDependentEntity

假设我们有一些看起来像这样的实体(我会尽量简化):

@Entity
class MainEntity {
  //nothing too special here
}

@Entity
class DependentEntity implements Serializable {

  @Id
  @OneToOne( fetch = FetchType.LAZY, optional = false )
  @JoinColumn( name = "mainEntityId", insertable = false, updatable = false, nullable = false )
  private MainEntity mainEntity;
}

@Entity
@IdClass(AnotherDependentEntityId.class)
class AnotherDependentEntity {

  @Id
  @ManyToOne( fetch = FetchType.LAZY, optional = false )
  @JoinColumn( name = "mainEntityId", insertable = false, updatable = false, nullable = false )
  private MainEntity mainEntity;

  @Id
  @Column ( name = "type", insertable = false, updatable = false, nullable = false )
  private SomeEnum type;
}


如您所见,每个DependentEntity最多可以有一个MainEntity,但可以有多个AnotherDependentEntity-每个SomeEnum值可以有一个。

现在,每当有人创建MainEntity时,我们也要创建必要的DependentEntityAnotherDependentEntity实例。我们正在尝试通过PostInsertEventListener和依赖的子会话来做到这一点,如下所示:

Session subSession = pEvent.getSession().sessionWithOptions()
    .autoClose( true)
    .autoJoinTransactions( true )
    .noInterceptor()
    .openSession();

subSession.saveOrUpdate( new DependentEntity( mainEntity ) );
subSession.saveOrUpdate( new AnotherDependentEntity ( mainEntity, SomeEnum.VALUE1 ) );


它对于DependentEntity效果很好,但对于AnotherDependentEntity则不行,我们无法弄清原因。

对于第二个saveOrUpdate(),我们收到以下消息:


  HHH000346:托管刷新期间发生错误[org.hibernate.HibernateException:复合标识符的任何部分都不能为null]
  (在org.hibernate.tuple.entity.AbstractEntityTuplizer $ IncredablySillyJpaMapsIdMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:367))


调试代码时,似乎在AnotherDependentEntity上执行了persist时,即使mainEntity属性是以前设置的,它也为null(并且正确设置了原始会话中的相同调试位置)。

这导致以下印象:mainEntity必须以某种方式设置为null,但即使值观察断点也不会被触发,因此它必须通过反射发生(并且我们验证了这两种情况下它都是相同的AnotherDependentEntity实例)。

所以这是问题:

有谁知道为什么/部分ID设置为空?也许我们做错了所有事情,并且有一种更好的方法(请注意:由于某些原因,我们不能将引用添加到MainEntity中,而只能使其级联)。

环境:Wildfly 10.1.0和Hibernate 5.2.7

编辑:

我们观察到的另一件事:在调试时,可以看到实体持久程序同时引用了该实体和id类的实例(即AnotherDependentEntityId)。 id-class包含两个值,即两个字段均为null,而实际实体的id已部分为null。

最佳答案

我在hibernate.atlassian中发现了一个问题。尝试使用此解决方案...

10-04 17:33