Hibernate 5持续存在并刷新一个以该实例结尾的实体,因为该实体在数据库中不存在

时间:2018-08-06 12:56:27

标签: java hibernate refresh seam persist

我刚刚将Hibnernate从3.3.1.GA版本迁移到了5.3.3.Final版本。所有人的思维都应该按预期的方式工作,只有一个人认为。如果我保留一个实体,则刷新该实体并将其提交到数据库中,然后该实体确实存在于数据库中(我使用select语句对其进行了检查)。但是,如果我刷新此实体。我收到以下异常:

Caused by: javax.persistence.EntityNotFoundException: No row with the given identifier exists: [this instance does not yet exist as a row in the database#14]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:133)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1336)
    at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1301)
    at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1295)
    at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:3625)
    at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:3601)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.jboss.seam.persistence.EntityManagerInvocationHandler.invoke(EntityManagerInvocationHandler.java:46)
    at com.sun.proxy.$Proxy131.refresh(Unknown Source)
    at service.CustomEntityHome.refreshInstance(CustomEntityHome.java:410)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
    at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
    at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97)
    at org.jboss.seam.util.Work.workInTransaction(Work.java:61)
    at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
    at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
    at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
    at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
    at service.AnredeHome_$$_javassist_seam_46.refreshInstance(AnredeHome_$$_javassist_seam_46.java)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335)
    ... 62 more

我调试了一下,这里是跟踪:

MutableEntityEntry(AbstractEntityEntry).getCompressedValue(AbstractEntityEntry$BooleanState) line: 516  
MutableEntityEntry(AbstractEntityEntry).isExistsInDatabase() line: 228  
DefaultRefreshEventListener.onRefresh(RefreshEvent, Map) line: 117  
DefaultRefreshEventListener.onRefresh(RefreshEvent) line: 48    
SessionImpl.fireRefresh(RefreshEvent) line: 1306    
SessionImpl.refresh(Object) line: 1257

在第516行MutableEntityEntry中有一个return语句

 return ( ( compressedState & state.getMask() ) >> state.getOffset() ) == 1;

变量为:

compressedState=17 == 0001 0001 
(looking in the code)
(0001 the 4. positions means 4 - existsInDatabase ???)    
(What does 17 mean ???)
state.getMask()=8192
state.getOffset()=13

so ==>

( ( 17 & 8192 ) >> 13 ) == 1 
==> False 
==> MutableEntityEntry(AbstractEntityEntry).isExistsInDatabase() line: 228  is false ???WHY???
==> in line 228 MutableEntityEntry 
throw new UnresolvableObjectException(
e.getId(),
"this instance does not yet exist as a row in the database"
);

为什么CompressedState为17?应该是什么,我该如何更改?

PS:我正在将Java 10与旧的Framework Seam 2.2.2。一起使用,最后我现在无法对其进行升级。 PPS:Seam 2.2.2是针对Hibernate 3进行编译的,为了迁移到Hibernate 5,我不得不扩展两个接口和一个类,因为它们在不同的NET包中移动了:

SessionImplementor

package org.hibernate.engine;
public interface SessionImplementor extends org.hibernate.engine.spi.SessionImplementor {}

EventSource

package org.hibernate.event;
public interface EventSource extends org.hibernate.event.spi.EventSource {}

和CustomHibernatePersistenceProvider

package org.jboss.seam.persistence;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.metadata.ClassMetadata;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

@Name("org.jboss.seam.persistence.persistenceProvider")
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Install(precedence = Install.APPLICATION, classDependencies = { "org.hibernate.Session",
        "javax.persistence.EntityManager" })
public class CustomHibernatePersistenceProvider extends HibernatePersistenceProvider {

    public static Object getVersion(final Object value, final Session session) {
        ClassMetadata classMetadata = getClassMetadata(value, session);
        return classMetadata != null && classMetadata.isVersioned() ? classMetadata.getVersion(value) : null;
    }

    private static ClassMetadata getClassMetadata(final Object value, final Session session) {
        Class entityClass = getEntityClass(value);
        ClassMetadata classMetadata = null;
        if (entityClass != null) {
            classMetadata = session.getSessionFactory().getClassMetadata(entityClass);
            if (classMetadata == null) {
                throw new IllegalArgumentException(
                        "Could not find ClassMetadata object for entity class: " + entityClass.getName());
            }
        }
        return classMetadata;
    }

    @Override
    public Object getVersion(final Object bean, final EntityManager entityManager) {
        try {
            return getVersion(bean, getSession(entityManager));
        } catch (NotHibernateException nhe) {
            return super.getVersion(bean, entityManager);
        }
    }

    private Session getSession(final EntityManager entityManager) {
        Object delegate = entityManager.getDelegate();
        if (delegate instanceof Session) {
            return (Session) delegate;
        } else {
            throw new NotHibernateException();
        }
    }

}

编辑:该错误已在Hibernate版本5.3.8中修复。和5.4.1。!!!

1 个答案:

答案 0 :(得分:0)

该错误已在Hibernate版本5.3.8中修复。和5.4.1。 !!!