在Hibernate代码中引发异常,是因为事务吗?
各位,我有下面的代码,它可以在多个测试系统上运行,但是在生产系统上出现了一个在Hibernate代码中引发异常,是因为事务吗?,hibernate,transactions,Hibernate,Transactions,各位,我有下面的代码,它可以在多个测试系统上运行,但是在生产系统上出现了一个NullPointerException。Hibernate为数据库中肯定存在的对象返回null。我认为这可能是由于糟糕的事务管理,但我不确定。有人看到问题吗?下面的代码都使用Hibernate包装器对象“db”。创建“db”时,从Hibernate的会话工厂创建了一个新会话,因此只有下面显示的代码使用该会话 从请求表中获取所有有效ID的列表。ID是主键字段: Criteria criteria = db.getSess
NullPointerException
。Hibernate为数据库中肯定存在的对象返回null。我认为这可能是由于糟糕的事务管理,但我不确定。有人看到问题吗?下面的代码都使用Hibernate包装器对象“db”。创建“db”时,从Hibernate的会话工厂创建了一个新会话,因此只有下面显示的代码使用该会话
从请求表中获取所有有效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);
助手方法:
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);
}
}
公共对象getObj(类clazz,标准crit)引发异常{
Object=null;
试一试{
object=session.createCriteria(clazz).add(crit.uniqueResult();
}捕获(例外e){
抛出新异常(e);
}
返回对象;
}
public void addObject(T object)引发异常{
试一试{
Transaction=session.beginTransaction();
session.save(对象);
trans.commit();
}捕获(例外e){
抛出新异常(e);
}
}
一些注意事项:
- InvalidRequest对象是一个Hibernate对象,它有一个 与请求对象的一个外键关系。换句话说 这就是为什么当我创建一个新的InvalidRequest时,我通过了 请求作为参数
- addObject方法使用事务,但getObj不使用。我不知道这对我的问题是否有什么特别的意义,但这只是一个提示
- 您会注意到,我从未在请求对象上使用过execute()或任何东西。我认为这意味着Hibernate将它们存储在会话缓存中一段时间。这是否使我的内存耗尽成为可能?或者,如果缓存太大,Hibernate会自动为我清除缓存吗?不管怎样,我不认为这是问题,因为我的代码爆炸得如此之快,但我不是积极的
criteria.setLockMode(your lock mode)
如果像我们一样,您使用一些通用代码来初始化您的条件,这里我们的代码摘录来处理这个问题
CriteriaImpl critiml = (CriteriaImpl) crit;
if (critiml.getProjection() != null) {
// lock mode is not compatible with projection criteria
// see bug entry https://hibernate.onjira.com/browse/HHH-3313
} else {
crit.setLockMode("obj", LockMode.NONE);
}
你能在getObj的Catch块中添加日志吗?@Andrew谢谢你的关注。一段时间(几个月)内,我无法在生产中再次部署此功能。在三台测试机器中的任何一台上进行测试时,它都不会抛出异常。我真的不知道如何继续,或者为什么Hibernate会抛出异常,而我所做的只是读取,然后将一个带有FK的(新)对象插入到我读入DB的对象中。在测试中,我只能在将对象添加到idList后从数据库中删除该对象时复制空指针异常。然而,这不会发生在生产上;我们不会从该表中删除。你确定id是唯一的吗?@Andrew是的,它是表中的主键有多少线程使用来自db的会话?这可能是并发性问题
CriteriaImpl critiml = (CriteriaImpl) crit;
if (critiml.getProjection() != null) {
// lock mode is not compatible with projection criteria
// see bug entry https://hibernate.onjira.com/browse/HHH-3313
} else {
crit.setLockMode("obj", LockMode.NONE);
}