简体   繁体   English

DAO层上的Junit测试为Postgresql exist()查询返回错误结果

[英]Junit test on DAO layer returns wrong results for postgresql exists() query

I'm testing my DAO layer using junit spring and jdbcTemplate. 我正在使用junit spring和jdbcTemplate测试我的DAO层。 I have for instance an Address class and an AddressDAO, and i've implemented a method exists(long id) that return true if the given Address id exits in the database and false otherwise: 例如,我有一个Address类和一个AddressDAO,我实现了一个方法exist(long id),如果给定的Address id在数据库中退出,则该方法返回true,否则返回false:

private static final String EXISTS_SQL = "SELECT EXISTS(SELECT * FROM \"ADDRESS\" WHERE id_address = ?)";

public boolean exists(long id){

    return this.jdbcTemplate.query(AddressDAOImpl.EXISTS_SQL,
                                   new Object[]{id},
                                   new ResultSetExtractor<Boolean>() {

            @Override
            public Boolean extractData(ResultSet resultSet) throws SQLException,DataAccessException {

                    boolean result = resultSet.next();
                    return result;
            }
        });
}

But when i execute the following junit test it fails: 但是,当我执行以下junit测试时,它会失败:

@Test
@Transactional
@Rollback(true)
public void testExists(){

    Candidate c = new Candidate();
    c.setEmail("email74");
    c.setPassword("password");

    candidateDAO.insert(c);

    Address a1 = new Address();
    a1.setRegistredUser(c);

    addressDAO.insert(a1, c.getId());

    boolean exists = addressDAO.exists(a1.getId());

    Address a2 = new Address();
    a2.setRegistredUser(c);

    addressDAO.insert(a2, c.getId());
    addressDAO.delete(a2);

    boolean dontExists = addressDAO.exists(a2.getId());

    System.out.println("exists = " + exists);
    System.out.println("dontExists = " + dontExists);

    Assert.assertTrue(exists == true);
    Assert.assertTrue(dontExists == false);
}

The exists method returns true if i insert an address and when i delete it 如果我插入地址并删除地址,则exist方法返回true

exists = true
dontExists = true

I don't understand why... Is it because it's executed inside a transaction and the address is maybe deleted at the end of it? 我不明白为什么...是因为它在事务内执行并且地址可能在其末尾删除了?

Thank you for helping. 感谢您的帮助。

This is because you're using the SELECT EXISTS([...]) in your SQL. 这是因为您在SQL中使用了SELECT EXISTS([...])。 This statement always returns a single row containing either true or false(0 or 1) and thus resultSet.next() always finds a row and since this function returns true if it did find a row you always get that true. 该语句始终返回包含true或false(0或1)的单行,因此resultSet.next()总是找到一行,并且由于此函数在找到一行后返回true,因此您总是会得到true。

If you want to check it this way, I suggest you simply remove the outer select(SELECT EXISTS) and only keep the inner. 如果要以这种方式进行检查,建议您只删除外部的select(SELECT EXISTS),而只保留内部的。 This way if no rows are found .next() will return false. 这样,如果找不到行,则.next()将返回false。 You should also not select all columns(using *), but a single column(preferably one with an index eg simply the primary key). 您也不应选择所有列(使用*),而应选择单个列(最好是带有索引的列,例如仅是主键)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM