让我们假设一个简单的Jsf示例,其中包含一个xhtml页面、一个ManagedBean、一个服务和一个JPA实体类。我有很多具有以下结构的用例:
- 在我的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);
}
}
托管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>
我想要实现的目标:
- 始终在每个请求中显示最新实体
我已经尝试过的东西
- 我试着在我的getter中使用dao获取。但你可以在任何地方看到这是一种糟糕的做法,因为jsf会多次调用getter(但目前我唯一能让它们真正保持最新的方法)
- 我尝试了RequestScoped Beans。但是Bean将在操作完成之前创建,并且不会在更新调用中重新创建,并且该值将过期(这是有道理的,因为这是一个请求,并且该请求从单击按钮开始)
- 我尝试了ViewScoped Beans,并在方法中添加了一个空的String返回值。我的希望是,这个重定向将在操作处理后重新创建Bean。但事实并非如此
- 我试着在每次使用方法后手动调用refetch函数。但我在同一个实体上有一些跨bean操作(我的真实实体比这个例子复杂得多)。因此,不同的Bean并不总是知道实体是否以及何时发生了变化
我的问题:
- 这可以用任何类型的Scope完成吗?假设每个请求都会再次从我的PostConstruct中获取数据
- getter方法中一定有比dao fetch更好的解决方案
这对我来说似乎是一个根本问题,因为获取最新数据对我的应用程序至关重要(数据经常更改)。
使用Primefaces 6.1和Wildfly 10.x
您对此有何看法?一个请求范围的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
}