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

Unable to iterate Cursor if the next element is null #1653

Closed
lysu opened this issue Sep 3, 2019 · 3 comments · Fixed by #1657
Assignees
Labels
bug
Milestone

Comments

@lysu
Copy link

@lysu lysu commented Sep 3, 2019

MyBatis version

3.5.1

Database vendor and version

mysql 5.7.27-0ubuntu0.19.04.1

or

TiDB 3.0 :D

Test case or example project

schema and data:

CREATE TABLE `t` (
  `v` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t values(null),(1);

mapper:

public interface TiMapper {
    @Select("select v from t")
    Cursor<String> queryTest();
}

test:

    @Resource
    private TiMapper tiMapper;

    @Transactional
    public void testCursorFetch() throws Exception {
        Cursor<String> cc = tiMapper.queryTest();
        final Iterator<String> iterator = cc.iterator();
        System.out.println(iterator.hasNext()); 
     }

Steps to reproduce

run testCursorFetch method

Expected result

        System.out.println(iterator.hasNext()); 

should be true

Actual result

be false...and 1 record has no chance to be output.

and if first record is NOT null, it will be true

we can work around this to change mapper to

    @Select("select v from t")
    Cursor<Map<String, Object>> queryTest();

and set mybatis.configuration.returnInstanceForEmptyRow=true

but IMHO, current cursor' impl is not very suitable, maybe many people meet this question

@harawata

This comment has been minimized.

Copy link
Member

@harawata harawata commented Sep 3, 2019

Thank you for the report, @lysu ,
As you found out, enabling returnInstanceForEmptyRow is the right solution.
Although you may be right about the default behavior being unintuitive, changing the default value of returnInstanceForEmptyRow breaks backward compatibility.
It makes sense, right?

@lysu

This comment has been minimized.

Copy link
Author

@lysu lysu commented Sep 4, 2019

@harawata Thank you for response~

yes, change the default value isn't a good choice.

but it really makes me confuse is:

when we set returnInstanceForEmptyRow=true and using Cursor<String> like this:

@Select("select v from t")
 Cursor<String> queryTest();

we will get nothing if t has two records null and 1, but using List<String>

@Select("select v from t")
 List<String> queryTest();

we can get null and 1...

Cursor and List got a different result for the same data event if returnInstanceForEmptyRow=true

@harawata

This comment has been minimized.

Copy link
Member

@harawata harawata commented Sep 4, 2019

Thank you for the explanation, @lysu !
And I am sorry that I misunderstood your point. I'll look into it.

@harawata harawata changed the title Cursor got nothing if first record is NULL Unable to iterate Cursor if the next element is null Sep 6, 2019
@harawata harawata self-assigned this Sep 7, 2019
@harawata harawata added the bug label Sep 7, 2019
@harawata harawata added this to the 3.5.3 milestone Sep 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.