Hibernate criterion.list()在神秘的情况下抛出NullPointerException

时间:2014-06-05 11:22:43

标签: java mysql hibernate debugging

我有一系列字符串,如[" foo"," bar"," baz"]。我试图找到包含这些单词之一的所有记录,例如:

SELECT * from city WHERE (name LIKE '%foo%' OR name LIKE '%bar%' OR name LIKE '%baz%')

有时也会出现一个州,因为我需要这样的查询:

SELECT * from city WHERE (name LIKE '%foo%' OR name LIKE '%bar%' OR name LIKE '%baz%') AND stateId = 11

我在这些搜索中使用Hibernate标准,这是我的方法:

public static List<City> findByPartialName(State state, String... names)
{
    if (names.length <= 0)
        return null;

    Criteria cr = session.createCriteria(City.class);
    boolean found = false;
    Criterion[] conditions = new Criterion[names.length];
    List<String> doneWords = new ArrayList<>( names.length );
    int i =0;
    for (String city : names)
    {
        city = city.trim();
        if (city.isEmpty() || city.length() < 3)
            continue;

        if ( doneWords.contains(city) )
            continue;

        found = true;
        conditions[i] = Restrictions.like("name", "%" + city + "%");
        doneWords.add(city);
        i++;
    }
    if (! found)
        return null;

    cr.add( Restrictions.or( conditions ) );

    if (state != null)
        cr.add( Restrictions.eq("state", state) );

    try
    {
        List<City> cities = cr.list();
        return cities;
    }
    catch (ObjectNotFoundException e)
    {
        return null;
    }
}

这是一个非常神秘的问题。如您所见,我使用名为ArrayList的{​​{1}}来跟踪已添加的任何字词。因此,如果我传入数组:doneWords,那么[Nashua, South, Nashua]只会在Nashua条件中添加一次,而不是重复。

如果我传入那个确切的数组(OR),那么我在这一行得到一个空指针异常:

[Nashua, South, Nashua]

但是如果我注释掉这一行:

List<City> cities = cr.list();

然后一切正常(但doneWords.add(city);在查询中添加两次,即使它只需要添加一次)。

如果我传入一个不包含任何重复单词的数组,例如,如果我只是传入Nashua,那么即使没有注释掉[South, Nashua]行,它也能正常工作。

我对此非常困惑。这里发生了什么?

P.S我将doneWords.add(city)选项设置为true,我可以看到在show_sql处抛出NullPointerException时没有执行任何查询。

1 个答案:

答案 0 :(得分:1)

问题似乎来自Criterion数组,您的数组大小与收到的名称数量相同,即使它包含空名称,小于3个字符或重复的名称。在这些情况下,数组将包含少于names.length Criterion对象,其余包含引用您的NPE的空引用。您应该使用List并使用toArray()将其传递给Restrictions.or(),而不是Criterion数组。