我有一个方法可以接收JPA Entity
及其相关的EntityManager
作为参数。 Entity
实例不是在类内部创建的,它很可能与其他类(如GUI等)共享。
该方法启动事务,对实体进行一些更改,最后提交事务。
万一提交失败,将调用EntityTransaction.rollback()
:根据JPA规范,然后将实体与管理器分离。
万一发生故障,应用程序需要丢弃待处理的更改,恢复实体e
中的原始值,然后将其重新附加到EntityManager
,以便对e
对象的各种分散引用将保持有效。问题出在这里:据我了解,这不是使用EntityManager
的API进行的简单操作:
由于EntityManager.refresh(e)
已分离,因此无法调用e
。
执行e = EntityManager.merge(e)
会为e
创建一个新实例:在运行时程序中对原始e
的所有其他引用都不会更新为新实例。这是主要问题。
此外(实际上对此还不太确定),EntityManager.merge(e)
将使用e
当前持有的值(即可能导致提交失败的值)更新新托管实例的值。相反,我需要重置它们。
样例代码:
public void method(EntityManager em, Entity e) {
EntityTransaction et = em.getTransaction();
et.begin();
...
// apply some modifications to the entity's fields
...
try {
et.commit();
} catch (Exception e) {
et.rollback();
// now that 'e' is detached from the EntityManager, how can I:
// - refresh 'e', discarding all pending changes
// - without instantiating a copy (i.e. without using merge())
// - reattach it
}
}
在这种情况下最好的方法是什么?
参考方案
可能的解决方案是:
public class YourClass {
private EntityManager em = ...; // local entity manager
public void method(Entity e) { // only entity given here
Entity localEntity = em.find(Entity.class, e.getId());
EntityTransaction et = em.getTransaction();
et.begin();
...
// apply some modifications to the local entity's fields
applyChanges(localEntity);
...
try {
et.commit();
// Changes were successfully commited to the database. Also apply
// the changes on the original entity, so they are visible in GUI.
applyChanges(e);
} catch (Exception ex) {
et.rollback();
// original entity e remains unchanged
}
}
private void applyChanges(Entity e) {
...
}
}
从实体获取或创建插入语句 - java是否存在具有值的现有实体类生成插入语句的可能性?编辑:我的意思是为实体类的实例生成一个插入语句,以单独执行该语句。提前致谢 java大神给出的解决方案 使用Fastnate,您可以为没有连接数据库的实体创建SQL语句:public String createSQL() { // Create your entity TestEntity entity = n…
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
如何获取查询中实体嵌套列表的总大小? - java我正在使用JPA,并且具有这样的数据结构:class ContainerA { long id; List<ContainerB> bs; } class ContainerB { long id; List<ContainerC> cs; } class ContainerC { long id; List<Device>…
Java:BigInteger,如何通过OutputStream编写它 - java我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…