皆さん、私は複数のテストシステムで動作する次のコードを持っていますが、実稼働システムではNullPointerException
. Hibernate は、確実にデータベースに存在するオブジェクトに対して null を返します。これはトランザクション管理が不十分なためだと思いますが、よくわかりません。誰かが問題を見ますか? 以下のコードはすべて、Hibernate ラッパー オブジェクト「db」を使用しています。「db」が作成されたときに、Hibernate のセッション ファクトリから新しいセッションが作成されたため、以下に示すコードのみがそのセッションを使用します。
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 オブジェクトと 1 対 1 の外部キー関係があります。つまり、新しい InvalidRequest を作成したときに、Request をパラメーターとして渡したのはそのためです。
- addObject メソッドは Transaction を使用しますが、getObj は使用しません。これが私の問題に特に重要かどうかはわかりませんが、単なるメモです。
- Request オブジェクトで evict() などを使用したことがないことに気付くでしょう。これは、Hibernate がそれらをセッション キャッシュにしばらく保存することを意味すると思います。それは私がメモリを使い果たした可能性がありますか?または、キャッシュが大きくなりすぎた場合、Hibernate は自動的にキャッシュをクリアしますか? いずれにせよ、私のコードはすぐに爆撃されたので、これが問題だとは思いませんが、私は肯定的ではありません.