我已经在JBoss上与hibernate / JPA一起工作了几个月,但有一个问题我找不到答案或解决方案。
似乎在创建新的实体bean时,至少在调用EntityManager.persist(entityBean)之前,我无法执行查询,否则会出现以下错误:TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing
一个例子:
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);
我的问题是,如果不首先保留“作业”(被注释掉的行),就无法调用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();
}