我必须同意@duffymo关于在启动事务之前进行验证的信息。处理数据库异常并将其呈现给用户非常困难。
出现分离异常的原因很可能是因为您认为已向数据库中写入了某些内容,然后调用了对象的remove或refresh,然后尝试再次编写一些内容。
你需要做的,而不是什么是创建一个
long-runningconversation与
flushMode设置为
MANUAL。然后,您开始保存内容,然后可以执行验证,如果可以,则再次保存。完成后,一切顺利,您致电
entityManager.flush()。它将所有内容保存到数据库。
如果发生故障,则不要冲洗。您只是
return null或
"error"带有一些信息。让我向您展示一些伪代码。
假设您有一个个人和组织实体。现在,您需要先存储人员,然后才能将人员放入组织。
private Person person;private Organization org;@Begin(join=true,FlushMode=MANUAL) //yes syntax is wrong, but you get the pointpublic String savePerson() {//Inside some save method, and person contains some data that user has filled through a form//Now you want to save person if they have name filled in (yes I know this example should be done from the view, but this is only an exampletry { if("".equals(person.getName()) { StatusMessages.instance().add("User needs name"); return "error"; //or null } entityManager.save(person); return "success";} catch(Exception ex) { //handle error return "failure";}}请注意,我们现在保存人,但尚未刷新交易。但是,它将检查您在entitybean上设置的约束。(@ NotNull,@
NotEmpty等)。因此,它将仅模拟保存。
现在,您可以为个人保存组织。
@End(FlushMode=MANUAL) //yes syntax is wrong, but you get the pointpublic String saveOrganization() {//Inside some save method, and organization contains some data that user has filled through a form, or chosen from comboboxorg.setPerson(person); //Yes this is only demonstration and should have been collection (OneToMany)//Do some constraint or validation checkentityManager.save(org);//Simulate saving org//if everything went okentityManager.flush() //Now person and organization is finally stored in the databasereturn "success";}您甚至可以在这里放入内容,
try catch并且只有在没有发生异常的情况下才返回成功,这样您就不会被抛出错误页面。
更新资料
您可以尝试以下方法:
@PersistenceContext(type=EXTENDED)EntityManager em;
这将使有状态Bean具有EJB3扩展的持久性上下文。只要bean存在,在查询中检索到的消息就保持受管状态,因此对有状态bean的任何后续方法调用都可以更新它们,而无需对EntityManager进行任何显式调用。这可以避免您的LazyInitializationException。您现在可以使用
em.refresh(user);



