java.lang.AbstractMethodError:at UserType.nullSafeSet()

时间:2017-10-02 16:14:03

标签: java hibernate jpa enums usertype

我有自定义enum值要保留在DB中。为此,我实施了StringValuedEnumStringValuedEnumTypeStingValuedEnumReflect以及我的enum实施StringValuedEnum

当我使用手动管理的JPA运行我的代码时,一切正常,我的枚举值保存在DB中。但是一旦我使用容器管理的JPA(Wildfly 8.2)运行应用程序,我在刷新实体管理器时会收到以下错误:

Caused by: java.lang.AbstractMethodError: yyy.xxx.util.StringValuedEnumType.nullSafeSet(Ljava/sql/PreparedStatement;Ljava/lang/Object;ILorg/hibernate/engine/spi/SessionImplementor;)V
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:158) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2843) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3121) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1335) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.flush(AbstractEntityManager.java:457) [wildfly-jpa-8.2.1.Final.jar:8.2.1.Final]
at zzz.ejb.facades.EntityManagerFacade.createObject(EntityManagerFacade.java:2024) [zzz-ejb.jar:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497) [rt.jar:1.8.0_66]
at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:407)
at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82) [wildfly-weld-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:93) [wildfly-weld-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) [wildfly-ejb3-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) [wildfly-jpa-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:407)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) [wildfly-weld-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) [wildfly-ee-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.component.interceptors.NonPooledEJBComponentInstanceAssociatingInterceptor.processInvocation(NonPooledEJBComponentInstanceAssociatingInterceptor.java:59) [wildfly-ejb3-8.2.1.Final.jar:8.2.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:251) [wildfly-ejb3-8.2.1.Final.jar:8.2.1.Final] 

看起来问题出现在池中(堆栈跟踪中显示了非池化的EJB组件)。

奇怪的是我无法调试它来理解问题,调试器不会停在方法内的任何断点上,而不是System.out.println()的工作。

问题

  • 手动和容器管理的JPA之间有什么区别导致持久化自定义类型的差异?
  • 如何解决?

2 个答案:

答案 0 :(得分:2)

UserType方法的签名nullSafeSet和nullSafeGet已从Hibernate 3更改为hibernate 4.您需要做的是在自定义用户类型中更新这些方法。

从中改变:

public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException

到此:

public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException

如您所见,“SessionImplementor”参数的类型已更改。

答案 1 :(得分:0)

我将解决方案放在这里,以便其他人也可以看到甚至使用,但是如果能提供确切的答案,将不胜感激。

我仅通过用@Entity @Table(name = "TABLE_NAME") public class EntityClass { // columns @Transient private EnumClass enumObj; @Column(name = "ENUM_COL_NAME") private String enumColField; // ...................... @PostLoad void fillTransient() { enumObj = EnumClass.fromValue(enumColField); } @PrePersist @PreUpdate void fillPersistent() { if (enumObj != null) { enumColField = enumObj.getField(); } } } 注释我的实体列就解决了我的问题,以便保留枚举名称。对于我的枚举没关系。但是如果枚举有一些字段并且您想要保留字段的值,那么可以在您的实体类中执行以下操作:

pubspec.yaml

这很完美,即使您的枚举有多个字段并且您想要将它们分别保存在数据库中,您也可以根据需要提供任意多的列,填充这些列并以提供的方式进行检索。