question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deeply nested (3+ levels) result map could cause IllegalArgumentException

See original GitHub issue

For some cases, when parse the mapper xml, it may be have incompleteStatements. The Configuration#buildAllStatements will parse them latter.

But it maybe do twice.

The method org.apache.ibatis.binding.MapperMethod.SqlCommand#resolveMappedStatement:

if (configuration.hasStatement(statementId)) {
    return configuration.getMappedStatement(statementId);
}

call the hasStatement method, the validateIncompleteStatements is true, so it will call buildAllStatements method and add the statement to mappedStatements and return true.

then call getMappedStatement, the validateIncompleteStatements is also true, it will call buildAllStatements again.

public MappedStatement getMappedStatement(String id) {
    return this.getMappedStatement(id, true);
}
 
public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
    if (validateIncompleteStatements) {
        buildAllStatements();
    }
    return mappedStatements.get(id);
}

it will throw ‘java.lang.IllegalArgumentException’ : Mapped Statements collection already contains…

so I think the code must be:

configuration.getMappedStatement(statementId, **false**)

and I wonder, when the incompleteStatements is build success, why not clear them?

The org.apache.ibatis.session.Configuration#buildAllStatements

/*
   * Parses all the unprocessed statement nodes in the cache. It is recommended
   * to call this method once all the mappers are added as it provides fail-fast
   * statement validation.
   */

It says that the method recommend to be called once, but in the code, there are many place call the org.apache.ibatis.session.Configuration#getMappedStatement(java.lang.String) method, it means if it parse the mapper xml and produce the incompleteStatements, when run the code it will throw already have mapped statement exception?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lythesiacommented, Nov 8, 2018

+1

I cannot understand why it has to be invoked twice. But the root reason is here: This is the snip from parsePendingResultMaps (and it’s same structure with parsePendingStatements

    synchronized (incompleteResultMaps) {
      Iterator<ResultMapResolver> iter = incompleteResultMaps.iterator();
      while (iter.hasNext()) {
        try {
          iter.next().resolve();
          iter.remove();
        } catch (IncompleteElementException e) {
          // ResultMap is still missing a resource...
        }
      }
    }

The pending-dealing procedure is invoked after current xml mapper is parsed, but its logic is WRONG! Consider this xml mapper dependency graph A<–B<–C, apparently you should do parsePendingXXX in recursive fashion when parsing C, or you have a chance to get A left incomplete! And then aforementioned exception is raised when buildAllStatements hit twice.

0reactions
harawatacommented, Nov 17, 2018

It should be fixed in the latest 3.5.0-SNAPSHOT. If there still is a similar problem (it’s possible), please create a test case (see the ones I created).

@lythesia , Thanks again for the repro!

Read more comments on GitHub >

github_iconTop Results From Across the Web

mybatis/mybatis-3 mybatis-3.5.0 on GitHub - NewReleases.io
Deeply nested (3+ levels) result map could cause IllegalArgumentException. #1176; Generic type parameter is not correctly resolved when the class hierarchy is ...
Read more >
Result Maps collection already contains value for - Stack ...
Invocation of init method failed; nested exception is java.lang. ... IllegalArgumentException: Result Maps collection already contains value for ...
Read more >
Deeply nested json in jackson-databind - Vulners
By using a large depth of nested objects, a remote attacker could exploit this vulnerability to cause a denial of service.
Read more >
Hibernate Mapping Exception – Unknown Entity - Baeldung
Hibernate Mapping Exception - Unknown Entity - causes and solutions.
Read more >
ConcurrentMap (Java 2 Platform SE 5.0) - P I R L
Nested classes/interfaces inherited from interface java.util.Map ... NullPointerException - if this map does not permit null keys or values, and the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found