java - 无法刷新注入(inject)到 JSF 2 Managed Bean 中的 JPA 2 实体

标签 java jsf-2 dependency-injection jpa-2.0

我在 session 范围内有一个 JSF 托管 bean,其中包含要跟踪的实体,例如经过身份验证的用户:

@ManagedBean
@SessionScoped
public class LoginController implements Serializable {
  User user;

  public User getUser() {
    return this.user;
  }

  public void setUser(User user) {
    this.user = user;
  }
  /* ... */
}

在另一个 bean 中,我必须注入(inject)用户以使用它来检索与其关联的角色列表,如下所示:

@ManagedBean
@ViewScoped
public class AnotherController implements Serializable {

  List<Role> roles;      

  @ManagedProperty(value="#{loginController.user}")
  User user;

  public someMethod() {
    /* Some stuff that insert other roles into database, referring the user as owner */
    roles = user.getRolesList();
  }
}

如果我使用someMethod通过ajax更新页面,roles列表仍然不会重新加载。 如果我在 user.getRolesList 之前插入 em.refresh(user) 我会收到此错误:

Can not refresh not managed object: model.User[ id=1 ].

谁能帮我理解这一点?为什么 session 范围的实体如果注入(inject)到另一个 bean 中就得不到管理?我怎样才能解决这个问题? 谢谢。

最佳答案

为了使实体能够刷新,需要对其进行管理,但您已经知道了。 为了对其进行管理,它需要是

  • 已重新获取
  • 合并然后刷新
  • 通过扩展的持久性上下文保持管理

前两个选项需要事务。

由于@ManagedBean@ViewScoped都不暗示任何类型的事务管理,这些bean中的实体将始终是分离的,因此您所经历的行为是预期的JPA 行为。

对于前两个选项,您可以将请求传递到后端中启用事务的 EJB,该 EJB 将合并并更新实体或返回新获取的实体。如果您不使用 Java EE 应用程序服务器,则可以使用 UserTransaction

对于第三个选项,您可以使用扩展的持久性上下文,该上下文不会在每次事务后关闭,因此实体仍然可以跨事务边界进行管理。

编辑 修复此问题的最简单选项是使用 UserTransaction 并假设依赖注入(inject)。

@Inject
UserTransaction tx;

    //merging and refreshing
    tx.begin();
    User managedUser = em.merge(user);
    em.refresh(managedUser);
    tx.commit();
    user = managedUser;

    //refetching
    tx.begin();
    user = em.find(User.class, user.getId);
    tx.commit();

关于java - 无法刷新注入(inject)到 JSF 2 Managed Bean 中的 JPA 2 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15063903/

相关文章:

c# - FreshMvvm 中的控制反转 (IOC)

dependency-injection - .net 核心中的依赖注入(inject),Autofac、StructureMap 和工厂方法,如果注册了多个实现,则解析接口(interface)

java - 如何将 RDF 转换为字符串

jsf-2 - post 在 JSF2 flash 作用域中设置一个值后,它在对页面的第二次 GET 请求中再次可见(Flash 作用域被认为是有害的)

java - 使用 java ee 8 security-api 进行 Wildfly 集群登录

java - 替换 c :foreach on ui:repeat

java - SessionMap 不保存 JSF 对象

c# - Autofac DI 并行.foreach

java - 如何从队列中获取所有现有消息并停止消费者

java - wildfly 数据源中的空闲超时后数据库连接未关闭