Skip to content

LONGVARCHAR is mapped to ClobTypeHandler #1484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yukihane opened this issue Feb 21, 2019 · 2 comments
Closed

LONGVARCHAR is mapped to ClobTypeHandler #1484

yukihane opened this issue Feb 21, 2019 · 2 comments
Assignees
Labels
enhancement Improve a feature or add a new feature
Milestone

Comments

@yukihane
Copy link
Contributor

yukihane commented Feb 21, 2019

Default type handler of LONGVARCHAR is ClobTypeHandler.
ClobTypeHandler calls getClob, but LONGVARCHAR does not support it.
It is supported only on CLOB and NCLOB(*1).

*1: JSR-000221 JDBC API Specification 4.3 pp.200, TABLE B-6 Use of ResultSet getter Methods to Retrieve JDBC Data Types

It seems ver.3.4 improvement works, related to #248, may be wrong.

MyBatis version

3.5.0

Database vendor and version

SAP Adaptive Server Enterprise Express Edition 16.0 SP03

JDBC driver:
jConnect (TM) for JDBC(TM)/16.0 SP03 PL02 (Build 27403)/P/EBF27518/JDK 1.6.0/jdbcmain/OPT/Mon Aug 28 18:41:14 PDT 2017

Test case or example project

https://github.com/yukihane/mybatis-longvarchar

Steps to reproduce

Create LONGVARCHAR column:

create table longvarchar_table (
  longvarchar_column char(1024)
)

(ASE's char(1024) is JDBC LONGVARCHAR.)

Execute query, defined as:

@Mapper
public interface LongvarcharTableMapper {
    @Select("select longvarchar_column from longvarchar_table")
    List<String> select();
}

Expected result

query completion normally

Actual result

Exception occurs:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'longvarchar_column' from result set.  Cause: java.sql.SQLException: JZ0TE: Attempted conversion between an illegal pair of types. Valid database datatypes are: '(text, Clob) (unitext, Clob) (unitext, NClob) (unitext, Clob) (image, Blob)'
### The error may exist in com/github/yukihane/mybatis/mapper/LongvarcharTableMapper.java (best guess)
### The error may involve com.github.yukihane.mybatis.mapper.LongvarcharTableMapper.select
### The error occurred while handling results
### SQL: select longvarchar_column from longvarchar_table
### Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'longvarchar_column' from result set.  Cause: java.sql.SQLException: JZ0TE: Attempted conversion between an illegal pair of types. Valid database datatypes are: '(text, Clob) (unitext, Clob) (unitext, NClob) (unitext, Clob) (image, Blob)'
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:144)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:77)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)
    at com.sun.proxy.$Proxy10.select(Unknown Source)
    at com.github.yukihane.mybatis.mapper.LongvarcharTableMapperTest.test(LongvarcharTableMapperTest.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'longvarchar_column' from result set.  Cause: java.sql.SQLException: JZ0TE: Attempted conversion between an illegal pair of types. Valid database datatypes are: '(text, Clob) (unitext, Clob) (unitext, NClob) (unitext, Clob) (image, Blob)'
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:83)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createPrimitiveResultObject(DefaultResultSetHandler.java:713)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:612)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:591)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:397)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
    ... 35 more
Caused by: java.sql.SQLException: JZ0TE: Attempted conversion between an illegal pair of types. Valid database datatypes are: '(text, Clob) (unitext, Clob) (unitext, NClob) (unitext, Clob) (image, Blob)'
    at com.sybase.jdbc4.jdbc.ErrorMessage.raiseError(ErrorMessage.java:767)
    at com.sybase.jdbc4.tds.TdsJdbcInputStream.getClob(TdsJdbcInputStream.java:2505)
    at com.sybase.jdbc4.jdbc.SybResultSet.getClob(SybResultSet.java:2485)
    at com.sybase.jdbc4.jdbc.SybResultSet.getClob(SybResultSet.java:2592)
    at org.apache.ibatis.type.ClobTypeHandler.getNullableResult(ClobTypeHandler.java:40)
    at org.apache.ibatis.type.ClobTypeHandler.getNullableResult(ClobTypeHandler.java:28)
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:81)
    ... 51 more

Workaround

Override default handler with StringTypeHandler.

LONGVARCHAR should support getString.(*1, pp.199)

@harawata
Copy link
Member

@yukihane ,
Thank you for the detailed report!
StringTypeHandler seems to be a better fit for LONGVARCHAR indeed.
We should consider switching the default type handler in TypeHandlerRegistry.

@cbegin @jeffgbutler ,
I checked the commit log and ML posts, but couldn't find the reason why ClobTypeHandler was chosen for LONGVARCHAR in the first place.
Any concern about the switch?

@harawata harawata added the enhancement Improve a feature or add a new feature label Mar 5, 2019
@harawata
Copy link
Member

harawata commented Mar 6, 2019

Hi @yukihane ,
The change has been committed (thank you @kazuki43zoo for taking a look at the PR!).
I'd appreciate if you could verify the fix with the latest 3.5.1-SNAPSHOT, just to be sure.
Thanks again!

@kazuki43zoo kazuki43zoo added this to the 3.5.1 milestone Mar 6, 2019
pulllock pushed a commit to pulllock/mybatis-3 that referenced this issue Oct 19, 2023
…om ClobTypeHandler to StringTypeHandler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve a feature or add a new feature
Projects
None yet
Development

No branches or pull requests

3 participants