Let's assume a simple Jsf example with a xhtml page, a ManagedBean, a service and an JPA entityClass. I have a lot of usecases with the following structure:
- Hold an entity in my bean
- Do actions on the entity
- Do rendering on the updated entity
Some easy example, so everyone will understand
Entity:
public class Entity {
private long id;
private boolean value;
...
// Getter and Setter
}
Dao:
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
}
and finally a simple 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>
What i want to achieve:
- Always show the up to date entity in every request!
What i already tried
- I tried with a dao-fetch in my getter. But you can read everywhere that this is bad practice, because jsf will call the getter more than once (but for now the only way i can keep them really up to date).
- I tried RequestScoped Beans. But the Bean will be created before the action is done, and is not recreated on the update call and the value will be outdated (Makes sense, since this is one request, and the request starts with the click on the button).
- I tried ViewScoped Beans and added an empty String return value to my method. My hope was, that this redirection will recreate the Bean after the action was processed. But this was not the case.
- I tried to call the refetch function manually after every method i used. But I have some cross bean actions on the same entity (My real entities are way more complex than this example). So the different Beans do not always know, if and when the entity has changed.
My Questions:
- Can this be done with any kind of Scope? Let's say that every request will fetch the data from my PostConstruct again.
- There must be a better solution than the dao-fetch in the getter method
This seems to be a fundamental problem for me, because getting the up to date data is essential for my app (data is changed often).
Using Primefaces 6.1 and Wildfly 10.x