A confusing "No enum constant" exception
See original GitHub issueMyBatis version
3.5.6
Database vendor and version
PostgreSQL 12.4 PostgreSQL Driver 42.2.19 Java 11.0.8
Test case or example project
public class Mybatis {
public static class History {
public enum Operation {
FOO,
BAR
}
int id;
int userId;
Operation operation;
History(int id, Operation operation) {
this.id = id;
this.userId = id; // Just for test
this.operation = operation;
}
}
public static void main(String[] args) throws IOException {
InputStream stream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
try (SqlSession session = factory.openSession()) {
HistoryMapper mapper = session.getMapper(HistoryMapper.class);
mapper.insert(new History(1, History.Operation.FOO));
mapper.insert(new History(2, History.Operation.BAR));
session.commit();
mapper.select();
}
}
}
HistoryMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="rockworkx.HistoryMapper">
<select id="select" resultType="History">
SELECT history.id, history.user_id, history.operation
FROM history
</select>
<insert id="insert" parameterType="History">
INSERT
INTO history(id, user_id, operation)
VALUES (#{id}, #{userId}, #{operation})
</insert>
</mapper>
mybatis.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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<typeAlias alias="History" type="rockworkx.Mybatis$History" />
</typeAliases>
<environments default="postgres">
<environment id="postgres">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
<property name="username" value="postgres" />
<property name="password" value="postgres" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="HistoryMapper.xml" />
</mappers>
</configuration>
Steps to reproduce
When I use an underscored column user_id
together with a java Enum type, Mybatis throws a IllegalArgumentException
with message No enum constant
.
But if I get rid of the underscored column user_id
, everything goes well.
And I also confused with the exception message:
Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
Why the user_id
column is related to the Enum type Operation
?
I guess that some implementation details dealing with underscored column or Enum type may be wrong.
Expected result
Actual result
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
### The error may exist in HistoryMapper.xml
### The error may involve rockworkx.HistoryMapper.select
### The error occurred while handling results
### SQL: SELECT history.id, history.user_id, history.operation FROM history
### Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
at com.sun.proxy.$Proxy4.select(Unknown Source)
at rockworkx.Mybatis.main(Mybatis.java:40)
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:87)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createUsingConstructor(DefaultResultSetHandler.java:710)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:693)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:657)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:630)
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:325)
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:89)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
... 7 more
Caused by: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
at java.base/java.lang.Enum.valueOf(Enum.java:240)
at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:49)
at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:26)
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
... 24 more
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
No enum const class even though iterating through values ...
A call to the method getByName("columnHeadings") is throwing java.lang.IllegalArgumentException: No enum const class labware.web.component.
Read more >[Solved] java.lang.IllegalArgumentException: No enum constant
Solutions: Always use valid constant values to resolve this issue and while trying to call this enum.valueOf() method always handle exception so ...
Read more >How to convert String to Enum in Java? ValueOf Example
valueOf method of Java Enum is used to retrieve Enum constant declared in Enum Type by passing ... IllegalArgumentException: No enum const class...
Read more >How to avaoid java.lang.IllegalArgumentException: No enum ...
Iam getting java.lang.IllegalArgumentException when iam using switch case through Enum contants. //Enum Constants declaration
Read more >Enum constant does not exist · Issue #165 · google/gson
Specifically the change from: return Enum.valueOf(classOfT, in.nextString()); (which throws an exception if the value does not match a constant) ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@shenc ,
Because the constructor takes two arguments
int
andOperation
and the second columns in the result set isuser_id
. Any of the following could be a solution:<resultMap />
with<constructor />
instead of relying on auto-mapping.OK,I’ll create a new issue soon