新关联实体的EntityNotFoundException

时间:2019-02-28 06:28:59

标签: java sql hibernate jpa persistence

我确实拥有DEVICE实体,该实体与下面定义的PROPERTIES实体有关联,

@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true)
private Properties properties;

其中PROPERTIES实体的ID如下,

@Id
@Column(name=ID)
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

我有两个并行执行的线程,

线程1->对于DEVICE-1,它将尝试获取PROPERTIES实体。它为null(未定义属性)。 因此,它将创建新的PROPERTIES-1并将其添加到DEVICE-1实体。

线程2->尝试删除DEVICE-1。在删除过程中,它抛出以下异常。

javax.persistence.EntityNotFoundException: Unable to find com.entity.properties with id 3
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:181)
    at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262)
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
    at org.hibernate.engine.internal.StatefulPersistenceContext.unproxyAndReassociate(StatefulPersistenceContext.java:603)
    at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89)
    at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:929)
    at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:906)
    at org.hibernate.engine.spi.CascadingActions$1.cascade(CascadingActions.java:74)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
    at org.hibernate.event.internal.DefaultDeleteEventListener.cascadeAfterDelete(DefaultDeleteEventListener.java:376)
    at org.hibernate.event.internal.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:312)
    at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:160)
    at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:920)
    at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:896)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:1214)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_131]
    at org.apache.aries.jpa.support.osgi.impl.EmProxy.invoke(EmProxy.java:43)
    at com.sun.proxy.$Proxy130.remove(Unknown Source)
    at Proxyc164ca4b_578b_459f_ace4_b5791bab5274.remove(Unknown Source)

这两个线程以几毫秒的差异同时执行时,会出现此问题。请帮助我了解此错误的可能性/原因。

1 个答案:

答案 0 :(得分:0)

经过一点分析,我可以看到休眠状态正在为具有适当ID的PROPERTIES实体创建代理。然后,在删除过程中,它尝试从会话中加载实际实体。在导致EntityNotFoundException的会话中找不到该实体的地方。

使用FetchType.EAGER将加载实际实体,并避免出现此异常。

休眠版本:4.3.6.Final

即使将隔离级别从REPEATABLE READ更改为READ COMMITTED,也可以解决该问题。 但是,作为解决方案,我们为EntityNotFoundException应用了重试机制。