MyBatis version

3.4.4

Situation One generic handler for several java classes: @MappedTypes({ FirtsClass,.., LastClass, ... 57 classes}) public class ConstantTranslationHandler & HasValue> extends BaseTypeHandler { ... }

Just one handler declared in ibatis-config

Result

  • 57 handlers are created when the application is started
  • When the resultmap is obtained, the handler is called correctly, but the wrong handler!!!
  • I debugged and i realized that there was one handler per each class but the TypeHandlerRegistry always return the last instanced handler .

Comment From: harawata

Hi @marnavleo ,

Does the ConstantTranslationHandler have a proper constructor? There are some concrete examples in the comments on #42 .

If you create a small example project like these and upload it to your GitHub repo, I will look into it.

Comment From: marnavleo

It has a constructor that receives one parameter: the type of the enum that calls the handler.

Enum

@XmlType(name = "claves_cargo")
@XmlEnum
public enum ClavesCargo implements HasValue  {
    AR,
    CN;
    public String value() {
        return name();
    }
    public static ClavesCargo fromValue(String v) {
        return valueOf(v);
    }
}

Interface

public interface HasValue {
    public String value() ;
}

Handler

@MappedTypes({ ClavesCargo.class, ClavesZona.class })
public class ConstantTranslationHandler<E extends Enum<E> & HasValue> extends BaseTypeHandler<E> {
       //Patch to inyect spring bean
    private ClavesSingleton clavesSingleton = null;
    private ClavesSingleton getClavesSingleton() {
        if(clavesSingleton==null){
            this.clavesSingleton=(ClavesSingleton) 
                                     ParcheIbatisSpring.getBean(ClavesSingleton.class);
        }
        return clavesSingleton;
    }

    private Class<E> type;
    private final E[] enums;
        //Constructor
    _public ConstantTranslationHandler(Class<E> type) {
        if (type == null)
          throw new IllegalArgumentException("Type argument cannot be null");
        this.type = type;
        this.enums = type.getEnumConstants();
        if (this.enums == null)
          throw new IllegalArgumentException(type.getSimpleName()
              + " does not represent an enum type.");
      }_
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.value());
    }

    @SuppressWarnings("unchecked")
    @Override
    public E getNullableResult(ResultSet rs, String columna) throws SQLException {
        String dato = rs.getString(columna);
        ClavesC clave = getClavesSingleton().getClaveBy(KeyEnumDictionary.getClave(type), dato);
        E output = null;        
        if(clave!=null){
            output =(E) EnumFactory.getInstanceOf(type, clave.getClaveEIAC());
        }
        return output;
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }

Mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeHandlers>
        <typeHandler handler="xxx.xxx.handler.ConstantTranslationHandler" "/>
    </typeHandlers>
</configuration>

The ibatis mapper

<resultMap type="xxx.xxx.Cargo" id="Cargo">
    <result column="numeroOrden" property="numeroOrden" javaType="java.lang.Long"/>
    <result column="claseCargo" property="claseCargo" javaType="xxx.xxx.ClavesCargo" typeHandler="aegon.aegon.vida.eiac.generacion.handler.ConstantTranslationHandler"/>
    <result column="importe" property="importe" javaType="java.math.BigDecimal"/>
    <result column="descripcionCargo" property="descripcionCargo" javaType="java.lang.String"/>
</resultMap>

Comment From: harawata

OK, then please create a small example project like these and upload it to your GitHub repo. Thanks!

Comment From: ljz0721cx

I have same problems as marnavleo,But I user a object,if not support?

public class EnDecryptHandler<E extends SecurityDTO & SecurityKey> extends BaseTypeHandler<SecurityKey> {
    private static Logger logger = LoggerFactory.getLogger(EnDecryptHandler.class);

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, SecurityKey parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setString(i, "str");
    }

Comment From: ljz0721cx

Sorry,I've already solved it

Comment From: harawata

This may be the same issue as #995 .