我已经在JBoss上与hibernate / JPA一起工作了几个月,但有一个问题我找不到答案或解决方案.
似乎在创建新的实体bean时,我至少在调用EntityManager.persist(entityBean)之前无法执行查询,否则会出现以下错误:
TransientObjectException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例
一个例子:
Job job = new Job();
Collection<Task> tasks = job.getTasks();
//entityManager.persist(job);
ActionPlan actionPlan = (ActionPlan) entityManager.createNamedQuery("ActionPlan.findByCommand").
setParameter("type",RunOperation.Install).getSingleResult();
Task task = Task.getTask(actionPlan);
task.setActionPlan(actionPlan);
tasks.add(task);
task.setJob(job);
我的问题是,如果不首先保留“ job”(被注释掉的行),就无法调用createNamedQuery. ActionPlan与Job有关系,但NamedQuery(findByCommand)不在Job上联接.令我困扰的是,当新创建的Job在这种情况下甚至没有意义时,我需要保留Job以便查询数据库.
将对persist()的调用移到代码段的末尾会产生上述错误.
我知道我正在处理的对象不是持久性的,但是持久性使得如果发生错误则无法回滚.
我相信有解决方案,因此,如果有人得到了答案,我将非常感激.我想念什么?
最佳答案
似乎无法查询数据库中还没有的内容是合理的,对吗?您可以做的就是开始使用事务.在一个简单的情况下,您的会话将有一个事务,该事务将一直打开,直到您关闭会话.届时交易将被提交,您的所有更改将被保留.您需要做的就是在发生错误时回滚事务.
附言Here at the bottom您可以找到“典型的交易应使用以下惯用法”.
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
//do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}