如何在托管 bean 中保存更改后使实体保持最新
How to keep entity up to date after saving changes in 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);
}
}
托管 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-fetch。但是你到处都可以读到这是不好的做法,因为 jsf 会不止一次调用 getter(但目前我唯一能让它们保持最新的方法)。
- 我尝试了 RequestScoped Beans。但是 Bean 将在操作完成之前创建,并且不会在更新调用时重新创建并且值将过时(有道理,因为这是一个请求,并且请求从单击按钮开始)。
- 我尝试了 ViewScoped Beans 并向我的方法添加了一个空字符串 return 值。我的希望是,此重定向将在处理完操作后重新创建 Bean。但事实并非如此。
- 我尝试在使用每种方法后手动调用 refetch 函数。但是我对同一个实体有一些跨 bean 操作(我的真实实体比这个例子复杂得多)。所以不同的 Bean 并不总是知道实体是否以及何时发生变化。
我的问题:
- 这可以用任何类型的范围来完成吗?假设每个请求都会再次从我的 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
}
让我们假设一个简单的 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);
}
}
托管 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-fetch。但是你到处都可以读到这是不好的做法,因为 jsf 会不止一次调用 getter(但目前我唯一能让它们保持最新的方法)。
- 我尝试了 RequestScoped Beans。但是 Bean 将在操作完成之前创建,并且不会在更新调用时重新创建并且值将过时(有道理,因为这是一个请求,并且请求从单击按钮开始)。
- 我尝试了 ViewScoped Beans 并向我的方法添加了一个空字符串 return 值。我的希望是,此重定向将在处理完操作后重新创建 Bean。但事实并非如此。
- 我尝试在使用每种方法后手动调用 refetch 函数。但是我对同一个实体有一些跨 bean 操作(我的真实实体比这个例子复杂得多)。所以不同的 Bean 并不总是知道实体是否以及何时发生变化。
我的问题:
- 这可以用任何类型的范围来完成吗?假设每个请求都会再次从我的 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
}