[
https://issues.apache.org/jira/browse/IBATIS-332?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12486695
]
Gabor Willner commented on IBATIS-332:
--------------------------------------
ditto. I would like to have that feature too...
> Exposing javaType (resultMap/parameterMap) attribute in TypeHandler methods
> for Superclass/Subclass handlers.
> -------------------------------------------------------------------------------------------------------------
>
> Key: IBATIS-332
> URL: https://issues.apache.org/jira/browse/IBATIS-332
> Project: iBatis for Java
> Issue Type: Improvement
> Components: SQL Maps
> Affects Versions: 2.1.7
> Environment: WebLogic 8.1.5, Oracle 9i, Solaris
> Reporter: Jay Blanton
>
> This improvement is inregards to TypeHandler and its usage with
> Superclasses/Subclasses. Currently we have an Abstract object
> (TypeSafeEnumeration) that users will extend to create their own specific
> implementations of our TypeSafeEnumeration. When they want to map this data
> type in iBatis, they have to create a specific handler for each
> implementation of the TypeSafeEnumeration. What we would like to accomplish
> is to create a single handler for the superclass. But in order to do
> this...methods like the getResult in the TypeHandler interface would need to
> know how to take a VARCHAR from the database and create the specific
> implementation of that superclass. This information is not available to
> getResult (but not needed in the setParameter), so therefore a handler must
> be created specific to each implementation. I would like to register a
> superclass with a global typeHandler in my sqlMapConfig that can handle the
> conversion for each specific implementation of that superclass, by utilizing
> the javaType (for example).
> So a superclass could be registered as the the global javaType with a
> superclass based TypeHandler. Then each resultMap/parameterMap could defined
> the specific implementation in the javaType and the TypeHandler could use
> that resultMap/parameterMap javaType to instantiate the specific version of
> that superclass.
> I have included below the TO that is getting mapped, and the Superclass
> (Abstract) that needs the TypeHandler, and two specific implementations of
> that TypeHandler:
> TO:
> public class ContactTO {
>
> private GenderType gender;
> private ContactMethodType contactMethod;
> public ContactMethodType getContactMethod() {
> return this.contactMethod;
> }
> public void setContactMethod(ContactMethodType contactMethod) {
> this.contactMethod = contactMethod;
> }
> public GenderType getGender() {
> return this.gender;
> }
> public void setGender(GenderType gender) {
> this.gender = gender;
> }
>
> }
> Superclass (Enum)
> import java.io.Serializable;
> import java.util.Hashtable;
> import java.util.Iterator;
> /**
> * Base class for type-safe Enumeration to provide a consistent interface and
> * common methods, and to make Castor-ation easier.
> */
> public abstract class AbstractTypeSafeEnumeration implements Serializable {
> private static Hashtable _types = new Hashtable();
> private String _value;
> private String _displayValue;
> public static final AbstractTypeSafeEnumeration getTypeByValue(String
> value, Class clazz ) {
> Hashtable classType = (Hashtable)_types.get(clazz.getName());
> AbstractTypeSafeEnumeration out =
> (AbstractTypeSafeEnumeration)classType.get(value);
> return out;
> }
> public static final AbstractTypeSafeEnumeration
> getTypeByDisplayValue(String displayValue, Class clazz)
> {
> Hashtable classType = (Hashtable)_types.get(clazz.getName());
> Iterator values = classType.values().iterator();
> AbstractTypeSafeEnumeration value = null;
> while (values.hasNext() && value == null)
> {
> AbstractTypeSafeEnumeration tempValue =
> (AbstractTypeSafeEnumeration) values.next();
> if (value.getDisplayValue().equals(displayValue)) {
> value = tempValue;
> }
> }
> return value;
> }
> protected AbstractTypeSafeEnumeration( String value, String displayValue
> ) {
> this._value = value;
> this._displayValue = displayValue;
> synchronized( _types ) {
> String className = this.getClass().getName();
> Hashtable classType = ( Hashtable )_types.get( className );
> if( classType == null ) {
> classType = new Hashtable();
> _types.put( className, classType );
> }
> classType.put( value, this );
> }
> }
> public final String getValue() {
> return this._value;
> }
> public final String getDisplayValue() {
> return this._displayValue;
> }
> }
> Implementations of Enum (located in ContactTO)
> import com.foo.to.AbstractTypeSafeEnumeration;
> /**
> * This class is a type-safe Enumeration of ContactMethodTypes.
> *
> * @author Jay Blanton
> */
> public class ContactMethodType extends AbstractTypeSafeEnumeration {
> public static final ContactMethodType PHONE = new ContactMethodType("P",
> "Phone");
> public static final ContactMethodType MAIL = new ContactMethodType("M",
> "Mail");
> public static final ContactMethodType UNKNOWN = new
> ContactMethodType("U", "Unknown");
> /**
> * Creates a new ContactMethodType object.
> *
> * @param intValue param
> * @param displayString param
> */
> private ContactMethodType(String value, String displayString) {
> super(value, displayString);
> }
> }
> import com.foo.to.AbstractTypeSafeEnumeration
> public class GenderType extends AbstractTypeSafeEnumeration {
> public static final GenderType FEMALE = new GenderType("F", "Female");
> public static final GenderType MALE = new GenderType("M", "Male");
> public static final GenderType UNKNOWN = new GenderType("U", "Unknown");
> /**
> * Creates a new GenderType object.
> *
> * @param intValue param
> * @param displayString param
> */
> private GenderType(String value, String displayString) {
> super(value, displayString);
> }
> }
> This is what we would like to see:
> Global Type Handler:
> <typeHandler javaType="com.foo.to.AbstractTypeSafeEnumeration"
> callback="com.foo.dao.datahandler.AbstractTypeSafeEnumerationTypeHandler"/>
> Specific Result Map for ContactTO:
> <resultMap id="loadContact" class="com.foo.to.ContactTO">
> <result property="gender" column="GENDER" jdbcType="VARCHAR"
> javaType="com.foo.to.GenderType"/>
> <result property="contactMethod" column="METHOD" jdbcType="VARCHAR"
> javaType="com.foo.to.ContactMethodType"/>
> </resultMap>
> Sample of a pseudo NewTypeHandler that has access to javaType:
> public class AbstractTypeSafeEnumerationTypeHandler implements NewTypeHandler
> {
> /**
> * This method overrides the default setParameter method in TypeHandler.
> *
> * @param ps param
> * @param i param
> * @param parameter param
> * @param jdbcType param
> *
> * @throws SQLException can be thrown
> */
> public void setParameter(PreparedStatement ps, int i, Object parameter,
> String jdbcType)
> throws SQLException {
> if(parameter == null) {
> JdbcType type =
> (JdbcType)JdbcType.getTypeByDisplayValue(jdbcType, JdbcType.class);
> int sqlType = Integer.parseInt(type.getValue());
> ps.setNull(i, sqlType);
> }
> else {
> AbstractTypeSafeEnumeration enum =
> (AbstractTypeSafeEnumeration)parameter;
> ps.setString(i, enum.getValue());
> }
> }
> private AbstractTypeSafeEnumeration getEnum(String value, String
> javaType) {
> Class clazz = null;
> try {
> clazz = Class.forName(javaType);
> }
> catch (ClassNotFoundException e) {
> throw new RuntimeException("Invalid javaType - This class does
> not exist: -> " + javaType, e);
> }
> return AbstractTypeSafeEnumeration.getTypeByValue(value, clazz);
> }
>
> /**
> * This method overrides the default getResult method in TypeHandler.
> *
> * @param rs param
> * @param columnName param
> *
> * @return returned
> *
> * @throws SQLException can be thrown
> */
> public Object getResult(ResultSet rs, String columnName, String javaType)
> throws SQLException {
> String result = rs.getString(columnName);
> return this.getEnum(result, javaType);
> }
> /**
> * This method overrides the default getResult method in TypeHandler.
> *
> * @param rs param
> * @param columnIndex param
> *
> * @return returned
> *
> * @throws SQLException can be thrown
> */
> public Object getResult(ResultSet rs, int columnIndex, String javaType)
> throws SQLException {
> String result = rs.getString(columnIndex);
> return this.getEnum(result, javaType);
> }
> /**
> * This method overrides the default getResult method in TypeHandler.
> *
> * @param cs param
> * @param columnIndex param
> *
> * @return returned
> *
> * @throws SQLException can be thrown
> */
> public Object getResult(CallableStatement cs, int columnIndex, String
> javaType)
> throws SQLException {
> String result = cs.getString(columnIndex);
> return this.getEnum(result, javaType);
> }
> /**
> * This method overrides the default equals method in TypeHandler.
> *
> * @param object param
> * @param dbVal param
> *
> * @return returned
> */
> public boolean equals(Object object, String dbVal) {
> return
> StringHelper.equals(((AbstractTypeSafeEnumeration)object).getValue(), dbVal);
> }
> /**
> * This method overrides the default valueOf method in TypeHandler.
> *
> * @param dbVal param
> *
> * @return returned
> */
> public Object valueOf(String dbVal) {
> return dbVal;
> }
> }
>
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.