如何在保存托管bean中的更改后保持实体最新

时间:2017-10-15 22:37:15

标签: jsf loading managed-bean

让我们假设一个简单的Jsf示例,其中包含xhtml页面,ManagedBean,服务和JPA entityClass。我有很多具有以下结构的用例:

  • 在我的bean中保存一个实体
  • 对实体执行操作
  • 在更新的实体上进行渲染

一些简单的例子,所以每个人都会理解

实体:

public class Entity {
     private long id;
     private boolean value;
     ...
     // Getter and Setter
}

道:

public class EntityService {

    // Entity Manger em and other stuff

    public void enableEntity(long id) {
        Entity e = em.find(id);
        e.value = true;
        em.persist(e);
    }
}

Managed Bean:

@ManagedBean
@RequestScoped/ViewScoped
public class EntityBean() {

    @EJB
    private EntityService entityService;

    private Entity entity;

    @PostConstruct
    public void init() {
        // here i fetch the data, to provide it for the getters and setters
        entity = entityService.fetchEntity();
    }

    public void enableEntity() {
        entityService.enableEntity(entity.getId);
    }

    // Getter and Setter
}

最后是一个简单的xhtml:

<html>
    // bla bla bla

    <h:panelGroup id="parent">
         <h:panelGroup id="disabled" rendered="#{not EntityBean.entity.value}>
              <p:commandButton value="action" action="#{EntityBean.enableEntity}" update="parent" />
         </h:panelGroup>

         <h:panelGroup id="enabled" rendered="#{EntityBean.entity.value}>
               // other stuff that should become visible
         </h:panelGroup>             
    </h:panelGroup>
</html>

我想要实现的目标:

  • 始终在每个请求中显示最新实体!

我已尝试过的内容

  • 我试着在我的吸气器中使用dao-fetch。但你可以随处读到这是不好的做法,因为jsf会不止一次地调用getter(但是现在我唯一可以让它们保持最新状态)。
  • 我尝试过RequestScoped Beans。但是Bean将在操作完成之前创建,并且不会在更新调用上重新创建,并且值将过时(这是有意义的,因为这是一个请求,并且请求从单击按钮开始)。 LI>
  • 我尝试了ViewScoped Beans并在我的方法中添加了一个空字符串返回值。我的希望是,这个重定向将在动作处理后重新创建Bean。但事实并非如此。
  • 我试图在我使用的每个方法后手动调用重新获取功能。但是我在同一个实体上有一些跨bean操作(我的真实实体比这个例子更复杂)。因此,不同的Beans并不总是知道实体是否以及何时发生变化。

我的问题:

  • 这可以用任何类型的范围完成吗?假设每个请求都会再次从我的PostConstruct中获取数据。
  • 必须有比getter方法中的dao-fetch更好的解决方案

这对我来说似乎是一个根本问题,因为获取最新数据对我的应用程序至关重要(数据经常更改)。

使用Primefaces 6.1和Wildfly 10.x

1 个答案:

答案 0 :(得分:1)

您如何看待这个? 将为更新创建的请求范围bean,并且每个请求只执行一次fetchEntity()。

<f:metadata>
  <f:viewAction action="#{entityBean.load()}" onPostback="true"/>
</f:metadata>

@ManagedBean
@RequestScoped
public class EntityBean() {

  @EJB
  private EntityService entityService;

  private Entity entity = null;

  public void load() {}
  public Entity getEntity() {
    if(entity == null) {
      entity = entityService.fetchEntity();
    }
    return entity;
  }
  public void enableEntity() {
    entityService.enableEntity(getEntity().getId);
  }

  // Getter and Setter
}