java.lang.AbstractMethodError at org.hibernate.type.CustomType.nullSafeGet

Hi,

We are upgrading our persistence layer from Hibernate 3.5.6.Final to Hibernate 5.2.15.Final. During our testing, we encountered the below error:

java.lang.AbstractMethodError
at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:119)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:82)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2854)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673)
at org.hibernate.loader.Loader.getRow(Loader.java:1562)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732)
at org.hibernate.loader.Loader.processResultSet(Loader.java:991)
at org.hibernate.loader.Loader.doQuery(Loader.java:949)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
at org.hibernate.loader.Loader.doList(Loader.java:2692)
at org.hibernate.loader.Loader.doList(Loader.java:2675)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507)
at org.hibernate.loader.Loader.list(Loader.java:2502)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1489)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1463)

This error is thrown for the below query at run time:

User user = entityManager.createQuery(“select u from User u where u.isActiveFl = true and u.username = :username”, User.class).setParameter(“username”, username).getSingleResult();

‘User’ is an entity class for ‘users’ table. This query used to work correctly before on 3.5.6.Final. Also, please note that the below query works fine on 5.2.15.Final:

User user = entityManager.createQuery(“select u from User u”, User.class).setMaxResults(1).getSingleResult();

I tried using Hibernate 5.1.0.Final and the query works correctly there. This is somehow an abstract method in 5.2.15.Final, which is probably why this exception is thrown. Is this a bug in 5.2.15.Final, or should I modify the query to something else? Please advise.

Thanks,
Abhishek

Usually an AbstractMethodError comes from a dependency issue: you might have a remaining artifact from an old version.

The UserType conteact has changed so you need to change your custom types to use the new method signatures.

For 5.2.15.Final, I am using these jars:

hibernate-core-5.2.15.Final.jar
hibernate-entitymanager-5.2.15.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-commons-annotations-5.0.1.Final.jar
jandex-2.0.3.Final.jar
dom4j-1.6.1.jar
antlr-2.7.7.jar
classmate-1.3.0.jar
javassist-3.22.0-GA.jar
jboss-logging-3.3.1.Final.jar
jboss-transaction-api_1.2_spec-1.0.1.Final.jar

For 5.1.0.Final, I am using these jars:

hibernate-core-5.1.0.Final.jar
hibernate-entitymanager-5.1.0.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-commons-annotations-5.0.1.Final.jar
jandex-2.0.0.Final.jar
dom4j-1.6.1.jar
antlr-2.7.7.jar
classmate-1.3.0.jar
javassist-3.20.0-GA.jar
jboss-logging-3.3.0.Final.jar
geronimo-jta_1.1_spec-1.1.1.jar

Should I do anything different for 5.2.15.Final?

We have just two custom classes that implement org.hibernate.usertype.UserType interface, and I have already changed the method signatures for nullSafeGet and nullSafeSet. These two custom types are not used in the above query or entity.

You need to add the source code for the UserTypes to see how it looks like.

Here is the code for one of our custom types. The other one is also the same, except for the nullSafeSet and nullSafeGet implementations. Is this what you were asking?

package com.demo.persistence.types;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

public class CharStringType implements UserType, Serializable {

  private static final long serialVersionUID = 1L;

  public CharStringType() {
    super();
  }

  @Override
  public int[] sqlTypes() {
    return new int[] { Types.CHAR };
  }

  @Override
  public Class<String> returnedClass() {
    return String.class;
  }

  @Override
  public boolean equals(Object x, Object y) throws HibernateException {
    return (x == y) || (x != null && y != null && (x.equals(y)));
  }

  @Override
  public int hashCode(Object x) throws HibernateException {
    return x.hashCode();
  }

  @Override
  public Object deepCopy(Object value) throws HibernateException {
    return (value == null) ? null : new String((String) value);
  }

  @Override
  public boolean isMutable() {
    return false;
  }

  @Override
  public Serializable disassemble(Object value) throws HibernateException {
    return (String) value;
  }

  @Override
  public Object assemble(Serializable cached, Object owner) throws HibernateException {
    return cached;
  }

  @Override
  public Object replace(Object original, Object target, Object owner) throws HibernateException {
    return original;
  }

  @Override
  public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor ssci, Object owner) throws HibernateException, SQLException {
    String val = rs.getString(names[0]);
    return trimEndSpaces(val);
  }

  @Override
  public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor ssci) throws HibernateException, SQLException {
    st.setString(index, (String) value);
  }


  /** 
   * @param string
   * @return String with trailing spaces removed or null if empty.
   */
  public String trimEndSpaces(String str) {
    //assert str != null;
    if (str == null || str.length() == 0) {
      return null;
    }
    int index = str.length();
    do {
      index--;
    } while (index > 0 && str.charAt(index) == ' ');
    return index <= 0 ? null : str.substring(0, index + 1);
  }

}

Adding the other one too, if needed:

package com.demo.persistence.types;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.TypeMismatchException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.SerializationException;
import org.hibernate.usertype.UserType;

/**
 * Maps a <code>String</code> to a {@link URI}.
 */
public class URIType implements UserType {

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
   */
  @Override
  public Object assemble(Serializable cached, Object owner) throws HibernateException {
    return cached;
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
   */
  @Override
  public Object deepCopy(Object object) throws HibernateException {
    return object;
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
   */
  @Override
  public Serializable disassemble(Object value) throws HibernateException {
    return (Serializable) value;
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object)
   */
  @Override
  public boolean equals(Object arg0, Object arg1) throws HibernateException {
    return arg0 == null ? arg1 == null : arg0.equals(arg1);
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
   */
  @Override
  public int hashCode(Object arg0) throws HibernateException {
    return arg0 == null ? 0 : arg0.hashCode();
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#isMutable()
   */
  @Override
  public boolean isMutable() {
    return false;
  }

  @Override
  public Object nullSafeGet(ResultSet rs, String[] cols, SharedSessionContractImplementor ssci, Object arg3) throws HibernateException, SQLException {
    String uriString = rs.getString(cols[0]);
    try {
      return rs.wasNull() ? null : new URI(uriString.replaceAll("\\s", "%20")); // replaceAll was added for older files that were stored with spaces in the filename.
    } catch (URISyntaxException e) {
      throw new SerializationException(String.format("URI String \"%s\" is not a valid URI.", uriString), e);
    }
  }

  @Override
  public void nullSafeSet(PreparedStatement ps, Object uri, int index, SharedSessionContractImplementor ssci) throws HibernateException, SQLException {
    if (uri == null) {
      ps.setNull(index, Types.VARCHAR);
    } else if (uri instanceof URI) {
      URI theURI = (URI) uri;
      ps.setString(index, theURI.toASCIIString());
    } else {
      throw new TypeMismatchException(String.format("Type %s cannot be converted to URI.", uri.getClass().getName()));
    }    
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
   */
  @Override
  public Object replace(Object original, Object target, Object owner) throws HibernateException {
    return original;
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#returnedClass()
   */
  @Override
  public Class<URI> returnedClass() {
    return URI.class;
  }

  /* (non-Javadoc)
   * @see org.hibernate.usertype.UserType#sqlTypes()
   */
  @Override
  public int[] sqlTypes() {
    return new int[] { Types.VARCHAR };
  }

}

I didn’t find any problem. Try to replicate it with this test case template.

http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/

Thanks for the suggestion. I was able to figure this out. Running JUnit tests on the User entity gave me this exception trace:

org.jasypt.hibernate4.type.EncryptedStringType.nullSafeGet(Ljava/sql/ResultSet;[Ljava/lang/String;Lorg/hibernate/engine/spi/SharedSessionContractImplementor;Ljava/lang/Object;)Ljava/lang/Object;
java.lang.AbstractMethodError: org.jasypt.hibernate4.type.EncryptedStringType.nullSafeGet(Ljava/sql/ResultSet;[Ljava/lang/String;Lorg/hibernate/engine/spi/SharedSessionContractImplementor;Ljava/lang/Object;)Ljava/lang/Object;
                at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:119)
                at org.hibernate.type.AbstractType.hydrate(AbstractType.java:82)
                at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2854)
                at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747)
                at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673)
                at org.hibernate.loader.Loader.getRow(Loader.java:1562)
                at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732)
                at org.hibernate.loader.Loader.processResultSet(Loader.java:991)
                at org.hibernate.loader.Loader.doQuery(Loader.java:949)
                at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
                at org.hibernate.loader.Loader.doList(Loader.java:2692)
                at org.hibernate.loader.Loader.doList(Loader.java:2675)
                at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507)
                at org.hibernate.loader.Loader.list(Loader.java:2502)
                at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
                at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392)
                at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
                at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1489)
                at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
                at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
                at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1463)

The problem is with the org.jasypt.hibernate4.type.EncryptedStringType.nullSafeGet() method. We use EncryptedStringType for password encryption. For some reason, this class/method information didn’t show up in the earlier exception traces, so I was completely left in the dark. I assumed that this was the problem with the query itself. From Hibernate 5.2.X onwards, the nullSafeSet() and nullSafeGet() method signatures have changed. The jasypt-hibernate4-1.9.0.jar that we use, implements the earlier method signatures, which is why it worked with Hibernate 5.1.0.Final.

This leads us to another problem. Jasypt has not released a version for Hibernate 5.2.X. The last one they have is for Hibernate 4.X and this is the one we use - http://www.jasypt.org/hibernate.html. I did some digging and came across this project - https://github.com/grelland/jasypt-hibernate5. It appears that this user has ported the Jasypt source code and implemented it for Hibernate 5.2.X. So, I checked out this project and built the ‘jasypt-hibernate5-1.9.3-SNAPSHOT.jar’ myself, after resolving some of the conflicts. I used this jar in my project along with Hibernate 5.2.15.Final jars, and now the query works correctly!

Thank you, for your time. Apologies for any confusion caused!

Just FYI, in case anyone needs it. It appears that the jar is available in the project itself - https://github.com/grelland/jasypt-hibernate5/blob/master/target/jasypt-hibernate5-1.9.3-SNAPSHOT.jar.

Hi,

I also face the same issue ABSTRACT METHOD ERROR, but we don’t use any encryption. Could you please help me how to resolve it. I attached the exception for your reference, i have tried many times but i couldn’t figure out which the nullSafeGet method is still referring to SessionImplementor instead of SharedSessionImplementor.

Caused by: java.lang.AbstractMethodError: com.triaset.spearhead.system.enumeration.ConfigurationCategoryTypeEnum.nullSafeSet(Ljava/sql/PreparedStatement;Ljava/lang/Object;ILorg/hibernate/engine/spi/SessionImplementor;)V
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:148)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:343)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.bindPositionalParameters(AbstractLoadPlanBasedLoader.java:363)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.bindParameterValues(AbstractLoadPlanBasedLoader.java:334)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.prepareQueryStatement(AbstractLoadPlanBasedLoader.java:253)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:185)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:121)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3967)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129)
at org.hibernate.internal.SessionImpl.access$2600(SessionImpl.java:164)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2696)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:975)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1075)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1033)
at org.jboss.as.jpa.container.AbstractEntityManager.find(AbstractEntityManager.java:213)
at com.triaset.spearhead.infra.repository.AbstractDaoJpaImpl.findByKey(AbstractDaoJpaImpl.java:66)
at com.triaset.spearhead.dayend.DayEndSchedulerPreNotificationService.getSchedulerConfiguration(DayEndSchedulerPreNotificationService.java:63)
at com.triaset.spearhead.dayend.DayEndSchedulerPreNotificationService.init(DayEndSchedulerPreNotificationService.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.8.0_181]
at java.lang.reflect.Method.invoke(Unknown Source) [rt.jar:1.8.0_181]
at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptor.java:96) [wildfly-ee-10.1.0.Final.jar:10.1.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doLifecycleInterception(Jsr299BindingsInterceptor.java:114)
at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:103)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73)
at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:53)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:107) [wildfly-ee-10.1.0.Final.jar:10.1.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.ee.component.AroundConstructInterceptorFactory$1.processInvocation(AroundConstructInterceptorFactory.java:28) [wildfly-ee-10.1.0.Final.jar:10.1.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.weld.injection.WeldInterceptorInjectionInterceptor.processInvocation(WeldInterceptorInjectionInterceptor.java:56)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.weld.ejb.Jsr299BindingsCreateInterceptor.processInvocation(Jsr299BindingsCreateInterceptor.java:100)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [wildfly-ee-10.1.0.Final.jar:10.1.0.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) [jboss-invocation-1.4.1.Final.jar:1.4.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275)
… 29 more