Jpa JSF2和x2B;EJB3+;使用用户控件提交或回滚CRUD?

Jpa JSF2和x2B;EJB3+;使用用户控件提交或回滚CRUD?,jpa,jsf-2,transactions,ejb,crud,Jpa,Jsf 2,Transactions,Ejb,Crud,我正在开发一个基于JSF2和Glassfish 3.1的JavaEE应用程序。应用程序必须在数据库表上提供CRUD操作。数据库表数据使用具有incell编辑行为的primeface数据表显示。 我想让用户 修改、添加和删除表中的元素,并 仅在用户确定其更改时提交(按命令按钮) 当用户想要放弃其更改时回滚 该表有一个实体,无状态EJB负责与entityManager的接口以访问数据库 问题是每次我删除表中的一行时,事务都会被提交,而用户没有任何控制权 如何实现这种用户对提交/回滚的控制?用户操

我正在开发一个基于JSF2和Glassfish 3.1的JavaEE应用程序。应用程序必须在数据库表上提供CRUD操作。数据库表数据使用具有incell编辑行为的primeface数据表显示。 我想让用户

  • 修改、添加和删除表中的元素,并
  • 仅在用户确定其更改时提交(按命令按钮)
  • 当用户想要放弃其更改时回滚
该表有一个实体,无状态EJB负责与entityManager的接口以访问数据库

问题是每次我删除表中的一行时,事务都会被提交,而用户没有任何控制权


如何实现这种用户对提交/回滚的控制?

用户操作频繁地反映在数据库中,导致不必要的数据库调用和流量增加。相反,您应该仅在用户最终确认后提交

应在对象或克隆的副本上进行更改,并让用户对其进行操作。当用户想要保存更改时,可以保存修改后的副本。如果要放弃更改,则可以从原始对象恢复初始状态

对于您当前的方法:

问题是每次我删除表中的一行时 事务在没有任何控制权留给用户的情况下被提交

因为默认刷新模式是
FlushModeType.AUTO
,所以可以将其更改为
FlushModeType.COMMIT

如何实现这种用户对提交/回滚的控制

通过使用
UserTransaction
接口的bean管理事务,您可以控制事务开始、提交、回滚等


编辑:根据JSR-317,托管实体可能会立即被持久化到数据库中,或者稍后会被持久化到特定于实现的数据库中

如果事务处于活动状态,则此事务的兼容实现 允许规范立即写入数据库(即。, 无论何时更新、创建和/或删除受管实体, 但是,实现的配置需要这样做 非延迟数据库写入不在此范围内 规格

问题是每次我删除表中的一行时,事务都会被提交,而用户没有任何控制权

这听起来很奇怪。如果您正在编辑数据表中的数据并发回这些编辑(通过AJAX或direct),并且数据来自无状态bean,那么除了处理分离的实体之外,它不能是其他任何东西

对这些实体或包含它们的列表的更改不会自动反映在数据库中。在这种情况下,没有自动提交事务的概念。我强烈地不同意上面纳扬给出的答案。是的,用户事务允许您控制提交,但这似乎根本不是您的问题

虽然您可能应该显示一些代码,但我的猜测是,您只是在用户的每次删除操作之后,在EJB服务上调用某种类型的delete方法,然后期望相同的事务和持久性上下文仍然存在。但是在一个无状态bean中,当您退出最初提供实体的方法时,这些实体就消失了

最好的策略是让用户操作只对
@ViewScoped
后台bean缓存的数据进行操作。然后,如果且仅当用户一次确认您调用EJB服务的更新操作以及所有更改项时。如果有一个父实体引用了一个包含您删除的所有项目的列表,则只需传递此父实体,并确保在关系上设置了“级联删除”

这就是说,有人支持你似乎认为你已经得到的模式。此模式涉及使用
@Stateful
会话bean和
扩展持久性上下文。在这种情况下,会话bean的持久性上下文将缓存所有更改,直到您再次将其与事务关联。如果您在会话bean的非事务性方法中执行删除操作,并使用
@Remove
entityManager.clear()
以及将方法另存为事务性@Remove方法(不需要在其主体中执行任何操作)将取消方法实现为非事务性,那么您将获得此效果


除非您牢牢掌握EJB和事务,否则最好使用第一种策略。

我已经在答案中添加了更多信息,请参阅编辑部分,如果不是,请告诉我。@NayanWadekar您引用的文本是在事务方法中保存实体时发生的情况。我的观点是,在用户确认之前,OP根本不应该调用这个事务性方法。谢谢,你是对的:当用户单击remove按钮时,ejb方法remove被调用(em.remove(em.merge(entity));)。“编辑”按钮也是如此(但仅限于em.merge),我错误地认为此操作应该由用户稍后提交,按正确的按钮。@ArjanTijms如果用户使用CMT在托管实体上操作,则更改将通过容器隐式反映在数据库中,有什么不同意的地方吗?@NayanWadekar这本身是正确的,但在用户确认您不应该使用CMT对托管实体进行操作之前;)换句话说,在JSF托管bean中对分离的实体进行操作。只有在用户确认后,才使用其默认CMT调用EJB服务。因此,不要在用户的每次删除操作之后调用ejb的
remove
方法。