繁体   English   中英

无法刷新注入JSF 2 Managed Bean的JPA 2实体

[英]Unable to refresh JPA 2 Entity injected into a JSF 2 Managed Bean

我在会话范围内有一个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中,我必须注入用户以使用它来检索与之关联的角色列表,如下所示:

@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 ].

任何人都可以帮我理解这个吗? 如果注入另一个bean,为什么会话范围实体不会被管理? 我怎样才能解决这个问题? 谢谢。

为了使权限能够刷新,需要对其进行管理,但您已经知道了。 要使它成为马来人,它必须是

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

前两个选项需要交易。

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

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

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

编辑修复此问题的最简单方法,使用UserTransaction并假设依赖注入。

@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();

首先,你应该分开你的顾虑,这基本上意味着你的支持bean 不应该直接执行任何业务逻辑 (这是你的评论暗示的/* Some stuff that insert other roles into database, referring the user as owner */ )。 相反,您可以使用@EJB注释在托管bean中注入UserService类,并通过commandComponents的操作调用其方法。

接下来,当您从数据库中获取实体并将其从持久性上下文中分离时 (读取:在事务结束时关闭持久性上下文),这意味着该实体不再由您的持久性服务进行管理,并且对您的实体的更改将不会反映在数据库中。 如果您想这样做,则需要调用EntityManager.merge() ,以使实体持久化。 当您希望将LoginController.user对象中的canges 持久保存到数据库时,您需要这样做。

因此,Kostja所说的是,当您想要获得用户对象与数据库中的行之间的最新对应关系时,您应该按照他提出的方式之一使您的EntityManager管理对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM