问题
In my application, I have an @ApplicationScoped
CDI bean to store some information from the database:
@Named
@ApplicationScoped
public class MrBean {
@EJB
private SoyaBean soyaBean;
private List<Toys> myToys;
@PostConstruct
public void prepareMrBean() {
this.myToys = soyaBean.getToys();
}
public void updateToys() {
this.myToys = soyaBean.getToys();
}
}
I also have a AddToy.xhtml page which would simply add a toy to the database. The backing bean is as following:
@Named
@RequestScoped
public class MrsBean {
@EJB
private SoyaBean soyaBean;
@Inject
private MrBean mrBean;
public void addToy() {
this.soyaBean.addToy();
this.mrBean.updateToys();
}
}
Since there is a new toy added to the database, I wanted to update the list of toys in mrBean. However, even though mrsBean called mrBean.updateToys()
, the list of toys in mrBean is not updated at all. I have another ViewToys.xhtml with a @RequestScoped
backing bean to view the list of toys and I didn't see the list get updated.
I'd be very grateful if someone could give me an advice on how to tackle this problem.
UPDATE: This is my SoyaBean implementation:
@Stateless
public class SoyaBeanImpl implements SoyaBean {
@PersistenceContext()
private EntityManager em;
@Override
public List<Toys> getToys() {
Query q = em.createQuery("SELECT T from Toys T");
return (List<Toys>) q.getResultList();
}
@Override
public void addToy() {
Toys newToy = new Toys();
em.persist(newToy);
}
}
UPDATE 2 I'd also really appreciate if someone could show me how I can achieve the same goal in any ways other than my troubling way.
Best regards,
James Tran
回答1:
Assuming that there are no major technical errors in your code, these errors are usually related to, as you have implied, the state of the data being returned by Entity manger.
Cluprit : The database?
Of course, you could have a cacheing issue in the underlying db. However, this is unlikely given your description of the system.out statements.
Culprit : The bean ?
The more likely culprit is that the query results are somehow being cached in the bean, or rather, in the query result set return value. If your test database allows dirty reads, that could be an explanation. This can be inspected by, for example, using an @Interceptor to refresh the query before any calls to getToys().
Another potential pitfall here : mistaking statelessness vs caching.
Finally : a brief word on statelessness. Although you are right that the stateless of the bean should result, generally speaking , in data which is not stale -- this is not always the case. The real definition of stateless beans in the EJB context is that those beans arent gauranteed to have state over the course of the application lifecycle.
In summary there are 3 different ways to get to the bottom of your issue :
1) Make sure the database isn't doing anything funny with dirty reads. 2) Test to see if intercepting the call to getToys(), and running / verifying the database query has no issues 3) Make sure that the type of statelessness that you want is actually being implemented by your ejb container.
回答2:
The problem was that the results of all SQL queries were cached. Hence, even though I tried to refresh the list of toys, it only received the old result. I solved this problem by setting the option Shared Cache Mode
in the file persistence.xml
to None
.
I believe not using cache at all is not a good option. Hence, I'd be very grateful if someone could show me how I can achieve the same result without having to turn off cache.
来源:https://stackoverflow.com/questions/8376652/why-my-applicationscope-cdi-bean-not-updated