org.json new JSONArray(List)具有hibernate延迟加载的StackOverFlowError

时间:2014-05-21 13:30:05

标签: java json hibernate org.json

我使用query.iterate()并将所有实体添加到ArrayList以进行二级缓存。但是当我将这个ArrayList更改为JSONArray时,就会出现StackOverFlowError。

但奇怪的是我使用query.list()。没有错!

我在这里有一个实体:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Word {
    @Id
    @GeneratedValue
    private int id;
    private String literal;
    private String chineseMean;
    //..getter and setter
}

和DAO对象的方法(使用iterate()):

public List<Word> getWords(final String wordBook, final int startId,
            final int length) {
        Session session = getSession();
        Query q = session.createQuery("from " + wordBook);
        q.setFirstResult(startId-1);
        q.setMaxResults(length);
        Iterator<Word> iterator = q.iterate();
        List<Word> wordList = new ArrayList<Word>();
        while(iterator.hasNext()){
            wordList.add(iterator.next());
        }
        return wordList;
    }

并使用list():

public List<Word> getWords_nobuffer(final String wordBook, final int startId,
            final int length) {
        Session session = getSession();
        Query q = session.createQuery("from " + wordBook);
        q.setFirstResult(startId-1);
        q.setMaxResults(length); 
        return q.list();
    }

错误位置(使用iterate()):

List<Word> words = worddao.getWords("Word",5, 10);
JSONArray ja = new JSONArray(words);//stackoverflowerror!!!!

这种方式没有错:

List<Word> words = worddao.getWords_nobuffer("Word",5, 10);
JSONArray ja = new JSONArray(words);//everything is ok

当我尝试使用它时:

List<Word> words = worddao.getWords("Word",5, 10);
List<Word> words2 = worddao.getWords_nobuffer("Word",5, 10);
JSONArray ja = new JSONArray(words2);//everything is ok too, all entities are selected from second level cache

StackOverFlowError是如何发生的?

1 个答案:

答案 0 :(得分:0)

发现问题.. hibernate中的实体使用惰性模式默认值。

所以在调试模式下,我们可以找到单词object被更改为:

{
    id : 0,
    chineseMean : null,
    literal : null,
    handler : JavassistLazyInitializer  // this is key! 
    //all the value of field was put in this object, this object must be used to implement lazy load.
}

所以,JSONArray出了问题...(啊......太复杂了,无法找到)

将实体更改为:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Proxy(lazy=false)//look at here!
public class Word {
    @Id
    @GeneratedValue
    private int id;
    private String literal;
    private String chineseMean;
    //..getter and setter
}

这使得JSONArray工作!