Как использовать XML ResultMap в аннотированном преобразователе для MyBatis Dynamic SQL? - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь использовать MyBatis Dynamic SQL для своего приложения и сталкиваюсь с некоторыми проблемами, когда следую указаниям по использованию XML-преобразователя вместе с аннотированным отображением, как описано в «XML Mapper для операторов соединения» на эта страница .

Я пытаюсь заставить работать следующий запрос:

SessionMapper mapper = sqlSession.getMapper(SessionMapper.class);
SessionTableSupport sessionMaster = new SessionTableSupport();

SelectStatementProvider stmt = select(
        sessionMaster.sessionId,
        sessionMaster.module,
        sessionMaster.startTime,
        sessionMaster.endTime,
        sessionMaster.eventId,
        sessionMaster.userId)
        .from(sessionMaster.sessionTable)
        .where(sessionMaster.module, isEqualTo("sample_module"))
        .build()
        .render(RenderingStrategy.MYBATIS3);

List<SessionResult> sampleSessions = mapper.selectMany(stmt);

Для справки, файл конфигурации выглядит примерно так:

<configuration>
    <settings> ... </settings>
    <environments> ... </environments>
    <mappers>
        <mapper resource="./mappers/SessionResultMapper.xml"/>
        <package name="mappers"/>
    </mappers>
</configuration>

Тогда вот мой xml mapper SessionResultMapper.xml:

<mapper namespace="SessionResultMapper">
    <resultMap id="SimpleResults" type="results.SessionResult">
        <id column="session_id" jdbcType="VARCHAR" property="sessionId" />
        <result column="module" jdbcType="VARCHAR" property="module" />
        <result column="start_time" jdbcType="BIGINT" property="startTime" />
        <result column="end_time" jdbcType="BIGINT" property="endTime" />
        <result column="event_id" jdbcType="INTEGER" property="eventId" />
        <result column="user_id" jdbcType="VARCHAR" property="userId" />
        <result column="institute" jdbcType="VARCHAR" property="institute" />
    </resultMap>
</mapper>

Вот аннотированный интерфейс маппера SessionMapper.java:

@Mapper
public interface SessionMapper {
    @SelectProvider(type=SqlProviderAdapter.class, method="select")
    @ResultMap("SimpleResults")
    List<SessionResult> selectMany(SelectStatementProvider selectStatement);
}

И, наконец, вот SessionResult.java:

public class SessionResult {

    private String sessionId;
    private String module;
    private long startTime;
    private long endTime;
    private int eventId;
    private String userId;
    private String institute;

    public SessionResult(
            String sessionId,
            String module,
            long startTime, 
            long endTime,
            int eventId, 
            String userId, 
            String institute) {

        super();
        this.sessionId = sessionId;
        this.module = module;
        this.startTime = startTime;
        this.endTime = endTime;
        this.eventId = eventId;
        this.userId = userId;
        this.institute = institute;
    }

    public SessionResult() {}

    // Getters and Setters
    ...
}

При выполнении вышеуказанного с использованием xml и аннотаций выдается следующее исключение:

Exception in thread "main" org.apache.ibatis.builder.IncompleteElementException: Could not find result map mappers.SessionMapper.SimpleResults
    at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346)
    at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290)
    at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseStatement(MapperAnnotationBuilder.java:364)
    at org.apache.ibatis.builder.annotation.MethodResolver.resolve(MethodResolver.java:33)
    at org.apache.ibatis.session.Configuration.lambda$buildAllStatements$3(Configuration.java:795)
    at java.util.Collection.removeIf(Collection.java:414)
    at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:794)
    at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:763)
    at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:758)
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.resolveMappedStatement(MapperMethod.java:254)
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:224)
    at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:50)
    at org.apache.ibatis.binding.MapperProxy.lambda$cachedMapperMethod$0(MapperProxy.java:62)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:62)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:57)
    at com.sun.proxy.$Proxy5.selectMany(Unknown Source)
    at test.TestMyBatisDynamic.main(TestMyBatisDynamic.java:70)
Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for mappers.SessionMapper.SimpleResults
    at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:933)
    at org.apache.ibatis.session.Configuration.getResultMap(Configuration.java:645)
    at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:344)
    ... 17 more

Но когда я использую аннотированную карту результатов, все работает правильно. К сожалению, я пытаюсь построить более сложную карту результатов с коллекциями и ассоциациями, поэтому использование чистых аннотаций не представляется возможным.

Я старался изо всех сил следовать примерам в документации как можно точнее. Я в полной растерянности ... Кто-нибудь знает, как решить эту проблему? Любая помощь или советы будут с благодарностью! Спасибо за ваше время заранее!

1 Ответ

1 голос
/ 02 апреля 2019

Благодаря посту в комментариях я узнал, что в моем коде произошел конфликт пространства имен.Чтобы исправить это, я изменил xml и аннотированные сопоставители следующим образом:

SessionResultMapper.xml

<mapper namespace="SessionResultMapper">
    <resultMap id="SimpleResults" type="results.SessionResult">
        ...
    </resultMap>
</mapper>

и соответственно в SessionMapper.java:

@ResultMap("SessionResultMapper.SimpleResults")

В основном, убедитесь, что путь [namespace].[resultMap id] соответствует xml и аннотированным картографам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...