ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Raymond McDermott" <...@mcdermott.be>
Subject Re: JAVA 1.5 enum > typehandler woes
Date Mon, 05 Nov 2007 10:54:59 GMT
I have not tried it on the select.  Good idea.  I will do that and post back
any new information.

I don't know how I would be more explicit for the INSERT.  Do I have to
decompose the definition of the parameter class?  Given that I know from the
debugger that the typehandler is definitely called on the INSERT, what
benefit would that bring?


On 05/11/2007, Niels Beekman <n.beekman@wis.nl> wrote:
>
>  Have you tried to define the typehandler explicitly on the resultmap or
> insert statement? Do both select and insert blow up?
>
>
>
> Niels
>  ------------------------------
>
> *From:* Raymond McDermott [mailto:ray@mcdermott.be]
> *Sent:* maandag 5 november 2007 10:45
> *To:* user-java@ibatis.apache.org
> *Subject:* Re: JAVA 1.5 enum > typehandler woes
>
>
>
> Thanks for the comments Niels.  I read the FAQ entry completely before
> posting and used it to drive the coded solution.
>
> In terms of the stacktrace, it is the complete stacktrace from Eclipse.  I
> think it gives enough to show that there is genuinely a problem with the
> typehandler.
>
> I have debugged it all the way line by line, including adding the iBATIS
> source code to the project.  The data is good and it should return a valid
> value - this is shown in the debugger - but somehow between the typehandler
> returning a value from the ENUM and coming back into iBATIS, the value goes
> null.
>
> That is why I wondered if there is something that I needed to do with the
> enum itself?
>
> Thanks for the continued support.
>
> Ray
>
>  On 05/11/2007, *Niels Beekman* <n.beekman@wis.nl> wrote:
>
> Hi,
>
>
>
> Are you sure this is the complete stacktrace? Did you try debugging?
>
> This error can be caused by numerous things, for example the property
> frequency can be null in your bean, ensure that you are handling the
> null-case in your typehandler, for a comprehensive explanation, see:
>
>
> http://opensource.atlassian.com/confluence/oss/display/IBATIS/How+do+I+use+a+Custom+Type+Handler+with+complex+property+or+Type+Safe+Enumeration
>
>
>
> Hth,
>
>
>
> Niels
>  ------------------------------
>
> *From:* Raymond McDermott [mailto:ray@mcdermott.be]
> *Sent:* zondag 4 november 2007 21:57
> *To:* user-java@ibatis.apache.org
> *Subject:* JAVA 1.5 enum > typehandler woes
>
>
>
> I am having some, ahem, fun trying to get enums persisting as varchars
> using iBatis 2.3 for Java
>
> Can I just check something... is there are a 'proper' way for iBATIS to
> persist enums or do we really have to write a typehandler?  Is this is
> something that the developer group will patch in 2.x or is there something
> more fundamental in the architecture that makes it a 3.0 feature?
>
> Also, I wonder if i have to do something extra in the definition of an
> ENUM to support access by the typehandler framework?
>
> Anyway, for the moment it seems that we are stuck with the, IMHO overly
> complex, task of scripting support for our enum types.  I am getting null
> pointers despite debugging the code and seeing that the typehandler is being
> properly registered and invoked.
>
> I have a simple enum class 'frequency':
>
> ---> ENUM START
>
> /**
>  * The frequency over which measurements are made
>  */
>
> public enum Frequency {
>     DAILY,
>     WEEKLY,
>     MONTHLY,
>     YEARLY
> }
>
>
> ---> ENUM END
>
> I used the generic enum typehandler from the FAQ:
>
> ---> GENERIC TYPEHANDLER START
>
> import java.sql.SQLException;
>
> import com.ibatis.sqlmap.client.extensions.ParameterSetter;
> import com.ibatis.sqlmap.client.extensions.ResultGetter;
> import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback ;
>
> public abstract class EnumTypeHandler<E extends Enum> implements
> TypeHandlerCallback
> {
>     private Class<E> enumClass_;
>
>     public EnumTypeHandler(Class<E> enumClass)
>     {
>         enumClass_ = enumClass;
>     }
>
>     @SuppressWarnings("unchecked")
>     public void setParameter(ParameterSetter setter, Object parameter)
>             throws SQLException
>     {
>         setter.setString(((E) parameter).name());
>     }
>
>     public Object getResult(ResultGetter getter) throws SQLException
>     {
>         return valueOf(getter.getString());
>     }
>
>     @SuppressWarnings("unchecked")
>     public Object valueOf(String s)
>     {
>         return Enum.valueOf(enumClass_, s);
>     }
> }
>
> ---> GENERIC TYPEHANDLER END
>
> Then I have the simple implementation as proposed in the FAQ:
>
> ---> SPECIFIC TYPEHANDLER START
>
> public class FrequencyTypeHandler extends EnumTypeHandler<Frequency> {
>
>     public FrequencyTypeHandler() {
>     super(Frequency.class);
>     }
>
> }
>
> ---> SPECIFIC TYPEHANDLER END
>
> ---> IBATIS CONFIGURATION FILE START
>
> <?xml version="1.0" encoding="UTF-8" ?>
>
> <!DOCTYPE sqlMapConfig
>     PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
>     "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
>
> <sqlMapConfig>
>
>     <typeHandler     javaType=" com.opengrail.circles365.domain.Frequency"
>                     jdbcType="VARCHAR"
>                     callback="
> com.opengrail.circles365.config.ibatis.typehandlers.FrequencyTypeHandler"/>
>
>
>     <typeHandler     javaType="
> com.opengrail.circles365.domain.MeasurementType"
>                     jdbcType="VARCHAR"
>                     callback="
> com.opengrail.circles365.config.ibatis.typehandlers.MeasurementTypeTypeHandler"/>
>
>
>     <!-- List the SQL Map XML files. They can be loaded from the
>          classpath, as they are here (com.domain.data...) -->
>
>     <sqlMap resource="com/opengrail/circles365/config/iBatis- User.xml"/>
>     <sqlMap resource="com/opengrail/circles365/config/iBatis-
> MeasurementItem.xml"/>
>
> </sqlMapConfig>
>
> ---> IBATIS CONFIGURATION FILE END
>
> ---> IBATIS SQLMAP FILE START
>
> <?xml version="1.0" encoding="UTF-8" ?>
>
> <!DOCTYPE sqlMap
>     PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
>     " http://ibatis.apache.org/dtd/sql-map-2.dtd">
>
> <sqlMap namespace="MeasurementItem">
>
>     <resultMap id="result" class="
> com.opengrail.circles365.domain.impl.MeasurementItemImpl ">
>         <result property="frequency" column="FREQUENCY"/>
>         <result property="measurementType" column="MEASUREMENTTYPE"/>
>         <result property="name" column="ITEMNAME"/>
>         <result property="derived" column="ISDERIVED"/>
>     </resultMap>
>
>     <select id="findMeasurementItemsByUserId" resultMap="result">
>         select     FREQUENCY, MEASURETYPE, ITEMNAME, ISDERIVED
>         from     C365MEASUREMENTITEM MI, C365USER U
>         where    U.USERID = #value#
>         and        MI.USERID = U.ID
>     </select>
>
>     <insert id="createMeasurementItem" parameterClass="
> com.opengrail.circles365.domain.MeasurementItem">
>         insert
>         into C365MEASUREMENTITEM (frequency, measuretype, itemname,
> isderived, userid)
>             select     #frequency#, #measurementType#, #name#, #derived#,
> u.id
>             from     c365user u
>             where     u.userid = #userId#
>     </insert>
>
> </sqlMap>
>
> ---> IBATIS SQLMAP FILE END
>
> Unit test trace ON INSERT:
>
> org.springframework.jdbc.UncategorizedSQLException: SqlMapClient
> operation; uncategorized SQLException for SQL []; SQL state [null]; error
> code [0];
> --- The error occurred in com/opengrail/circles365/config/iBatis-
> MeasurementItem.xml.
> --- The error occurred while applying a parameter map.
> --- Check the createMeasurementItem-InlineParameterMap.
> --- Check the parameter mapping for the 'frequency' property.
> --- Cause: java.lang.NullPointerException; nested exception is
> com.ibatis.common.jdbc.exception.NestedSQLException:
> --- The error occurred in com/opengrail/circles365/config/iBatis-
> MeasurementItem.xml.
> --- The error occurred while applying a parameter map.
> *--- Check the createMeasurementItem-InlineParameterMap.
> --- Check the parameter mapping for the 'frequency' property.
> *--- Cause: java.lang.NullPointerException
> Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
> --- The error occurred in com/opengrail/circles365/config/iBatis-
> MeasurementItem.xml .
> --- The error occurred while applying a parameter map.
> --- Check the createMeasurementItem-InlineParameterMap.
> --- Check the parameter mapping for the 'frequency' property.
> --- Cause: java.lang.NullPointerException
>     at
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(
> GeneralStatement.java:94)
>     at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(
> SqlMapExecutorDelegate.java:505)
>     at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(
> SqlMapSessionImpl.java:90)
>     at
> org.springframework.orm.ibatis.SqlMapClientTemplate$10.doInSqlMapClient(
> SqlMapClientTemplate.java:383)
>     at org.springframework.orm.ibatis.SqlMapClientTemplate.execute (
> SqlMapClientTemplate.java:193)
>     at org.springframework.orm.ibatis.SqlMapClientTemplate.update(
> SqlMapClientTemplate.java:381)
>     at
> com.opengrail.circles365.data.impl.MeasurementItemDaoImpl.createMeasurementItem(
> MeasurementItemDaoImpl.java:13)
>     at
> com.opengrail.circles365.service.impl.MeasurementItemManagementImpl.createMeasurementItem
> (MeasurementItemManagementImpl.java:25)
>     at
> com.opengrail.circles365.tests.ServiceImplementationTests.testGoodMeasurementItem(
> ServiceImplementationTests.java:56)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at sun.reflect.NativeMethodAccessorImpl.invoke(
> NativeMethodAccessorImpl.java:39)
>     at sun.reflect.DelegatingMethodAccessorImpl.invoke (
> DelegatingMethodAccessorImpl.java:25)
>     at java.lang.reflect.Method.invoke(Method.java:585)
>     at junit.framework.TestCase.runTest(TestCase.java:154)
>     at junit.framework.TestCase.runBare(TestCase.java:127)
>     at org.springframework.test.ConditionalTestCase.runBare(
> ConditionalTestCase.java:69)
>     at junit.framework.TestResult$1.protect(TestResult.java:106)
>     at junit.framework.TestResult.runProtected(TestResult.java :124)
>     at junit.framework.TestResult.run(TestResult.java:109)
>     at junit.framework.TestCase.run(TestCase.java:118)
>     at junit.framework.TestSuite.runTest(TestSuite.java:208)
>     at junit.framework.TestSuite.run (TestSuite.java:203)
>     at
> org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(
> JUnit3TestReference.java:130)
>     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(
> TestExecution.java:38)
>     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
> RemoteTestRunner.java:460)
>     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(
> RemoteTestRunner.java:673)
>     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (
> RemoteTestRunner.java:386)
>     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(
> RemoteTestRunner.java:196)
> Caused by: java.lang.NullPointerException
>     at
> com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap.setParameter(
> BasicParameterMap.java:165)
>     at
> com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap.setParameters
> (BasicParameterMap.java:125)
>     at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(
> SqlExecutor.java :79)
>     at
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteUpdate
> (GeneralStatement.java:200)
>     at
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(
> GeneralStatement.java :78)
>     ... 27 more
>
> Do any of you folks have any ideas?
>
> Thanks in advance for your support.
>
> Ray
>
>
>
>
> --
> Ray McDermott
> GSM 047/32.53.854
>



-- 
Ray McDermott
GSM 047/32.53.854

Mime
View raw message