Skip to content
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

Column names with a period messes up name mapping #13

Closed
jhsheets opened this issue Mar 12, 2013 · 4 comments · Fixed by #3076
Closed

Column names with a period messes up name mapping #13

jhsheets opened this issue Mar 12, 2013 · 4 comments · Fixed by #3076
Assignees
Labels
enhancement Improve a feature or add a new feature
Milestone

Comments

@jhsheets
Copy link

Edit: I've done a little more testing. It looks like any period in the column name messes it up; spaces have nothing to do with it.

I'm using version 3.2.1. I don't think the ResultHandler is necessary, but it's the scenario I had in my environment where I noticed the bug.

<?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="IncorrectColumnNameTest">
    <select id="test" resultType="HashMap">
        select 1 as [Space No Period], 2 as [Space. With Period]
    </select>
</mapper>
public interface IncorrectColumnNameTest 
{
    public void test(ResultHandler resultHandler);
}
public Class IncorrectColumnNameTestDao
{
    public boolean test(FileWriter fileOutput) throws SQLException
    {
        final SqlSession session = MyBatisSession.openSession(con);
        try
        {
            final ConsoleResultHandler fileHandler = new ConsoleResultHandler();
            final DetailsViewExportMapper mapper = session.getMapper(DetailsViewExportMapper.class);
            mapper.test(fileHandler);
        } finally {
            session.close();
        }

        public static class ConsoleResultHandler implements ResultHandler
        {
            public void handleResult(ResultContext rc) 
            { 
                final Map<String,Object> row = (Map<String,Object>)rc.getResultObject();
                System.out.println( StringUtils.join(row.keySet(), ",") );
                System.out.println( StringUtils.join(row.values(), ",") );
            }

            private String join(Collection<? extends Object> data)
            {
                String join = "";
                for (Object o : data)
                {
                    join += o.toString() + ", "
                }
                return join;
            }
        }
    }
}

MyBatis output

905 [main] DEBUG IncorrectColumnNameTest.test - ooo Using Connection [com.mpti.reportlogiq.server.db.TraceConnection@16ef71]
905 [main] DEBUG IncorrectColumnNameTest.test - ==> Preparing: select 1 as [Space No Period], 2 as [Space. With Period]
906 [main] DEBUG IncorrectColumnNameTest.test - ==> Parameters:
937 [main] TRACE IncorrectColumnNameTest.test - <== Columns: Space No Period, Space. With Period
937 [main] TRACE com.mpti.reportlogiq.server.db.mappers.IncorrectColumnNameTest.test - <== Row: 1, 2

Expected output

Space No Period, Space. With Period,
1, 2,

Actual output

Space No Period, Space,
1, { With Period=2},

@harawata
Copy link
Member

It seems to be the expected behavior.
If a map key contains period, MyBatis creates a nested map.

Please see the following test case: org.apache.ibatis.reflection.MetaObjectTest.shouldDemonstrateDeeplyNestedMapProperties()
https://github.com/mybatis/mybatis-3/blob/master/src/test/java/org/apache/ibatis/reflection/MetaObjectTest.java#L211

Do you agree to close this issue as invalid?

@jhsheets
Copy link
Author

I think I disagree.

autoMappingBehavior is set to PARTIAL by default, which isn't supposed to auto-map nested result mappings.

@harawata
Copy link
Member

Well, it is a little bit confusing, but autoMappingBehavior=PARTIAL/FULL is applied only to nested s.
Consider the following java class and the query.

public class SomeBean {
  private String name;
  private SomeBean child;
  // accessors
}
<select id="selectBean" resultType="SomeBean">
  select 'A' as "name", 'B' as "child.name"
</select>

Whether autoMappingBehavior is PARTIAL or FULL, this select maps 'child.name' of the resulting bean.
So, I think MyBatis works consistently here.

Having said that, it might be a valid enhancement request: provide an easy way to return non-nested map when a map key contains period.
As I don't use resultType="map" very often, I will leave this issue open for others to review.

@emacarron
Copy link
Member

+1 Iwao. A dot has meaning, is not just a character.

This works like this by design. Not a bug in my opinion.

harawata added a commit to harawata/mybatis-3 that referenced this issue Jan 24, 2024
It's now  possible to write a custom Map wrapper that allows keys that contain period (dot) `.` or brackets `[]`.
Also, it's now possible to write a custom Map wrapper by extending the built-in `MapWrapper`.

Should fix mybatis#13 mybatis#2298 mybatis#3062
@harawata harawata added enhancement Improve a feature or add a new feature and removed wontfix labels Jan 28, 2024
@harawata harawata self-assigned this Jan 28, 2024
@harawata harawata added this to the 3.5.16 milestone Jan 28, 2024
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

Successfully merging a pull request may close this issue.

3 participants