大家,我有以下代码,它适用于多个测试系统,但在生产系统上失败,带有NullPointerException
. Hibernate 为肯定在数据库中的对象返回 null。我认为这可能是由于交易管理不善,但我不确定。有人看到问题吗?下面的代码都使用了一个 Hibernate 包装对象,'db'。创建“db”时,从 Hibernate 的会话工厂创建了一个新的 Session,因此只有下面显示的我的代码使用该 Session。
从 Request 表中获取所有有效 ID 的列表。ID 是主键字段:
Criteria criteria = db.getSession().createCriteria(Request.class);
Criterion crit = Restrictions.and(Restrictions.eq("status", "valid"));
criteria.add(crit).setProjection(Projections.property("id"));
List<Integer> results = (List<Integer>)criteria.list();
List<Integer> idList = new ArrayList<Integer>();
for (Integer id : results) idList.add(id);
下面的代码是引发 NullPointerException 的原因。请参阅 catch 块中的代码注释。辅助方法如下所示:
for (Integer id : idList){
Request current = null;
try{
current = (Request) db.getObj(Request.class, Restrictions.eq("id", id));
// ... other business logic in here
InvalidRequest newInvalidRequest = new InvalidRequest(current.getId(), current);
db.addObject(newInvalidRequest);
}
} catch (Exception e){
//This Exception gets thrown and caught. However the log message never prints.
//Further along in the code, I get a NullPointerException because
//the variable 'current' was null and therefore I can't call current.getId()
//(which is why the log message never printed).
//but how could current be null when 'id' is in the Request table?
Log.error("ID = " + current.getId(), e);
}
}
辅助方法:
public <T> Object getObj(Class<T> clazz, Criterion crit) throws Exception {
Object object = null;
try {
object = session.createCriteria(clazz).add(crit).uniqueResult();
} catch (Exception e) {
throw new Exception(e);
}
return object;
}
public <T> void addObject(T object) throws Exception {
try {
Transaction trans = session.beginTransaction();
session.save(object);
trans.commit();
} catch (Exception e) {
throw new Exception(e);
}
}
一些注意事项:
- InvalidRequest 对象是一个 Hibernate 对象,它与 Request 对象具有一对一的外键关系。换句话说,这就是为什么当我创建一个新的 InvalidRequest 时,我将 Request 作为参数传入。
- addObject 方法使用 Transaction 但 getObj 不使用。我不知道这对我的问题是否有任何特殊意义,但这只是一个注释。
- 你会注意到我从未在 Request 对象上使用过 evict() 或任何东西。我认为这意味着 Hibernate 将它们存储在会话缓存中一段时间。这是否使我有可能内存不足?或者如果缓存太大,Hibernate 会自动为我清除缓存吗?无论哪种方式,我都认为这不是问题,因为我的代码很快就被炸毁了,但我并不积极。