From 1dd79f4eb420e7657367db2c5cb84a037986ce11 Mon Sep 17 00:00:00 2001 From: Iwao AVE! Date: Mon, 18 Sep 2023 14:49:04 +0900 Subject: [PATCH 1/2] Added a failing test for #2956 --- .../defaults/DefaultParameterHandlerTest.java | 4 +- .../enum_with_method/EnumWithMethodTest.java | 9 ++++ .../submitted/enum_with_method/Mood.java | 53 +++++++++++++++++++ .../enum_with_method/MoodTypeTypeHandler.java | 49 +++++++++++++++++ .../submitted/enum_with_method/User.java | 9 ++++ .../submitted/enum_with_method/CreateDB.sql | 7 +-- .../submitted/enum_with_method/Mapper.xml | 4 +- .../enum_with_method/mybatis-config.xml | 5 ++ 8 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/test/java/org/apache/ibatis/submitted/enum_with_method/Mood.java create mode 100644 src/test/java/org/apache/ibatis/submitted/enum_with_method/MoodTypeTypeHandler.java diff --git a/src/test/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandlerTest.java b/src/test/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandlerTest.java index 3075c3044cc..56a8aed4edb 100644 --- a/src/test/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandlerTest.java +++ b/src/test/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandlerTest.java @@ -19,9 +19,9 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.sql.PreparedStatement; import java.sql.SQLException; diff --git a/src/test/java/org/apache/ibatis/submitted/enum_with_method/EnumWithMethodTest.java b/src/test/java/org/apache/ibatis/submitted/enum_with_method/EnumWithMethodTest.java index 91af7b811e7..f9f694aed89 100644 --- a/src/test/java/org/apache/ibatis/submitted/enum_with_method/EnumWithMethodTest.java +++ b/src/test/java/org/apache/ibatis/submitted/enum_with_method/EnumWithMethodTest.java @@ -49,6 +49,7 @@ void shouldGetAUser() { Mapper mapper = sqlSession.getMapper(Mapper.class); User user = mapper.getUser(1); Assertions.assertEquals("User1", user.getName()); + Assertions.assertEquals(Mood.GOOD, user.getMood()); } } @@ -60,7 +61,15 @@ void shouldInsertAUser() { user.setId(2); user.setName("User2"); user.setCur(Currency.Dollar); + user.setMood(Mood.BAD); mapper.insertUser(user); + sqlSession.commit(); + } + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + User user = mapper.getUser(2); + Assertions.assertEquals("User2", user.getName()); + Assertions.assertEquals(Mood.BAD, user.getMood()); } } diff --git a/src/test/java/org/apache/ibatis/submitted/enum_with_method/Mood.java b/src/test/java/org/apache/ibatis/submitted/enum_with_method/Mood.java new file mode 100644 index 00000000000..9a415af500b --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/enum_with_method/Mood.java @@ -0,0 +1,53 @@ +/* + * Copyright 2009-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ibatis.submitted.enum_with_method; + +public enum Mood { + GOOD(1) { + @Override + public String getMessage() { + return "Yeehaw"; + } + }, + BAD(2) { + @Override + public String getMessage() { + return "whatevs"; + } + }; + + private int value; + + private Mood(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static Mood fromValue(int i) { + for (Mood t : values()) { + if (t.value == i) { + return t; + } + } + throw new IllegalArgumentException("Unknown value for Mood: " + i); + } + + public abstract String getMessage(); +} diff --git a/src/test/java/org/apache/ibatis/submitted/enum_with_method/MoodTypeTypeHandler.java b/src/test/java/org/apache/ibatis/submitted/enum_with_method/MoodTypeTypeHandler.java new file mode 100644 index 00000000000..5cb43900e5d --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/enum_with_method/MoodTypeTypeHandler.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ibatis.submitted.enum_with_method; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +public class MoodTypeTypeHandler extends BaseTypeHandler { + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, Mood parameter, JdbcType jdbcType) throws SQLException { + ps.setInt(i, parameter.getValue()); + } + + @Override + public Mood getNullableResult(ResultSet rs, String columnName) throws SQLException { + return Mood.fromValue(rs.getInt(columnName)); + } + + @Override + public Mood getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return Mood.fromValue(rs.getInt(columnIndex)); + } + + @Override + public Mood getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return Mood.fromValue(cs.getInt(columnIndex)); + } + +} diff --git a/src/test/java/org/apache/ibatis/submitted/enum_with_method/User.java b/src/test/java/org/apache/ibatis/submitted/enum_with_method/User.java index 1aedc275741..1dbfd59ab6e 100644 --- a/src/test/java/org/apache/ibatis/submitted/enum_with_method/User.java +++ b/src/test/java/org/apache/ibatis/submitted/enum_with_method/User.java @@ -20,6 +20,7 @@ public class User { private Integer id; private String name; private Currency cur; + private Mood mood; public Integer getId() { return id; @@ -44,4 +45,12 @@ public Currency getCur() { public void setCur(Currency cur) { this.cur = cur; } + + public Mood getMood() { + return mood; + } + + public void setMood(Mood mood) { + this.mood = mood; + } } diff --git a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/CreateDB.sql b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/CreateDB.sql index 5d71de23772..5c9c05dee86 100644 --- a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/CreateDB.sql +++ b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2009-2022 the original author or authors. +-- Copyright 2009-2023 the original author or authors. -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ drop table users if exists; create table users ( id int, name varchar(20), - cur varchar(20) + cur varchar(20), + mood int ); -insert into users (id, name, cur) values(1, 'User1', 'RMB'); +insert into users (id, name, cur, mood) values(1, 'User1', 'RMB', 1); diff --git a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/Mapper.xml b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/Mapper.xml index ad2aeb02686..9b4a87e8253 100644 --- a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/Mapper.xml +++ b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/Mapper.xml @@ -1,7 +1,7 @@ insert into users - values (#{id}, #{name}, #{cur}) + values (#{id}, #{name}, #{cur}, #{mood}) diff --git a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/mybatis-config.xml b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/mybatis-config.xml index 5e5335869c1..37deca6b2c6 100644 --- a/src/test/resources/org/apache/ibatis/submitted/enum_with_method/mybatis-config.xml +++ b/src/test/resources/org/apache/ibatis/submitted/enum_with_method/mybatis-config.xml @@ -22,6 +22,11 @@ + + + + From 06ec2c0c1bc8115062922406b7393cebc683633e Mon Sep 17 00:00:00 2001 From: Iwao AVE! Date: Mon, 18 Sep 2023 16:13:34 +0900 Subject: [PATCH 2/2] Registered type handler should be used for anonymous enum Should fix #2956 --- .../org/apache/ibatis/type/TypeHandlerRegistry.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java b/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java index 93f9fdb7c72..849d4cba5ea 100644 --- a/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java +++ b/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java @@ -263,11 +263,13 @@ private Map> getJdbcHandlerMap(Type type) { if (type instanceof Class) { Class clazz = (Class) type; if (Enum.class.isAssignableFrom(clazz)) { - Class enumClass = clazz.isAnonymousClass() ? clazz.getSuperclass() : clazz; - jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(enumClass, enumClass); + if (clazz.isAnonymousClass()) { + return getJdbcHandlerMap(clazz.getSuperclass()); + } + jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(clazz, clazz); if (jdbcHandlerMap == null) { - register(enumClass, getInstance(enumClass, defaultEnumTypeHandler)); - return typeHandlerMap.get(enumClass); + register(clazz, getInstance(clazz, defaultEnumTypeHandler)); + return typeHandlerMap.get(clazz); } } else { jdbcHandlerMap = getJdbcHandlerMapForSuperclass(clazz);