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

Some records are missing in result #580

Closed
avackova opened this issue Feb 19, 2016 · 9 comments
Closed

Some records are missing in result #580

avackova opened this issue Feb 19, 2016 · 9 comments

Comments

@avackova
Copy link

MyBatis version

3.3.0

Database vendor and version

DB2 for AS400

Test case or example project

Steps to reproduce

Result map:

    <resultMap type="cz.pse.agata.commons.dto.Security" id="detailed_security">
    <result property="id" column="VAID"/>
    <result property="issueId" column="VAIDVA"/>
    <result property="effectiveDate" column="VAEFDT"/>
    <result property="bic" column="VABIC"/>
    .
    .
    .
    <association property="isin" column="VACVAL" javaType="cz.pse.agata.commons.dto.ISIN">
        <result property="isin" column="VACVAL"/>
    </association>
    <association property="legalPerson" javaType="cz.pse.agata.commons.dto.LegalPerson"
            resultMap="legalPerson" columnPrefix="specialist_person_"/>
    </association>  
    <association property="emitent" column="VAEMIT" javaType="cz.pse.agata.commons.dto.LegalPerson"
        resultMap="cz.pse.agata.commons.dto.mapper.LegalPersonMapper.legalPerson"/>
    <association property="administrator" column="VAIDAD" javaType="cz.pse.agata.commons.dto.LegalPerson" 
        resultMap="legalPerson"/>
    <association property="changeReason" column="VAIDCD" javaType="cz.pse.agata.commons.dto.ChangeReason">
        <result property="id" column="CDID"/>
        <result property="reason" column="CDTEXT"/>
    </association>
    <association property="tail" javaType="Object">
         <discriminator javaType="String" column="VATVAL">
            <case value="000" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="520" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="100" resultMap="cz.pse.cp.dto.mapper.BondMapper.Bond"/>
            <case value="150" resultMap="cz.pse.cp.dto.mapper.BondMapper.Bond"/>
            <case value="200" resultMap="cz.pse.cp.dto.mapper.BondMapper.Bond"/>
            <case value="500" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="510" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="610" resultMap="cz.pse.cp.dto.mapper.WarrantMapper.Warrant"/>
            <case value="660" resultMap="cz.pse.cp.dto.mapper.WarrantMapper.Warrant">
                <result property="id" column="WAID"/>
            </case>
            <case value="600" resultMap="cz.pse.cp.dto.mapper.InvestementCertificateMapper.InvestementCertificate"/>
            <case value="650" resultMap="cz.pse.cp.dto.mapper.InvestementCertificateMapper.InvestementCertificate"/>
            <case value="300" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="305" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
            <case value="400" resultType="cz.pse.agata.commons.dto.SecurityTailImpl">
                <result property="issueId" column="VAIDVA"/>
            </case>
        </discriminator>
    </association>
  </resultMap>

Expected result

List of four items:

==>  Preparing: with dates as ( select vaefdt as dat from ....
 ==> Parameters: 109735(Long), 109735(Long), ....
<==      Total: 4

Actual result

List of three items.

After some debugging I realized, that it happens (probably) because 2 of the 4 rows have all data the same except tail values (method org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForNestedResultMap(ResultSetWrapper, ResultMap, ResultHandler, RowBounds, ResultMapping)):

 private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    final DefaultResultContext resultContext = new DefaultResultContext();
    skipRows(rsw.getResultSet(), rowBounds);
    Object rowValue = null;
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
      final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
      final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
==>      Object partialObject = nestedResultObjects.get(rowKey);             <==
      // issue #577 && #542
      if (mappedStatement.isResultOrdered()) {
==>      if (partialObject == null && rowValue != null) {
          nestedResultObjects.clear();
          storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
        }     <==
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);
      } else {
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);
        if (partialObject == null) {
          storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
        }
      }
    }
    if (rowValue != null && mappedStatement.isResultOrdered() && shouldProcessMoreRows(resultContext, rowBounds)) {
      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
  }

Note marked (==> <==) text above: for the 2nd iteration proper rowValue is created, but it is not added to the result, because partialObject is not null.

@emacarron
Copy link
Member

Hi! Can you plese check 3.3.1? (just in case)

@avackova
Copy link
Author

The same behavior with 3.3.1.

@avackova
Copy link
Author

The problem is not only for discriminator. The issue occurs for following simple mapping also:

  <resultMap type="cz.pse.cp.dto.Invoice" id="invoice">
    <result property="active" column="P0PLAT" typeHandler="cz.pse.commons.mybatis.handler.BooleanCZShort"/>
    <result property="calculatedPrice" column="P0MTMV"/>
    <association property="invoice" resultMap="cz.pse.dto.mapper.InvoiceDataMapper.invoiceData"/>
  </resultMap>

Resulting list contains only records, which are different on fields P0PLAT and P0MTMV!!!!!
(Record, that has both fields of the same value as any of the previous records is not added to resulting list).

@avackova avackova changed the title Some records are missing in result when using discriminator Some records are missing in result Mar 12, 2016
@harawata
Copy link
Member

I think what you are seeing is the expected behavior.
Please see the comments in these similar reports ( #512 , #522 )

@avackova
Copy link
Author

I'm not sure if it is not a bug for discriminator. Without discriminator I can avoid using association by using dot notation. But it is impossible with discriminator. Is there a way to obtain all records in this case?

@h7io
Copy link

h7io commented May 4, 2016

Hi,
bug should be fixed in #682

@harawata
Copy link
Member

harawata commented May 5, 2016

I should have mentioned that you can define 'id' elements without mapping it to the Java object.
As your result map only contains 'association' elements, it could be a row number.
Please see the test case here.

@kazuki43zoo
Copy link
Member

Hi @avackova , How is it ?

@harawata
Copy link
Member

I'll close. This is not a bug and there is a workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants