Why my @ApplicationScope CDI bean not updated?

末鹿安然 提交于 2019-12-22 12:54:41

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!