为什么我的@ApplicationScope CDI bean没有更新?

在我的应用程序中,我有一个@ApplicationScoped CDI bean来存储数据库中的一些信息:

 @Named @ApplicationScoped public class MrBean { @EJB private SoyaBean soyaBean; private List myToys; @PostConstruct public void prepareMrBean() { this.myToys = soyaBean.getToys(); } public void updateToys() { this.myToys = soyaBean.getToys(); } } 

我还有一个AddToy.xhtml页面,它只是将一个玩具添加到数据库中。 支持bean如下:

 @Named @RequestScoped public class MrsBean { @EJB private SoyaBean soyaBean; @Inject private MrBean mrBean; public void addToy() { this.soyaBean.addToy(); this.mrBean.updateToys(); } } 

由于数据库中添加了一个新玩具,我想更新mrBean中的玩具列表。 但是,即使mrsBean调用了mrBean.updateToys()mrBean.updateToys()中的玩具列表也根本没有更新。 我有另一个带有@RequestScoped支持bean的ViewToys.xhtml来查看玩具列表,我没有看到列表得到更新。

如果有人能就如何解决这个问题给我一个建议,我将非常感激。

更新 :这是我的SoyaBean实现:

 @Stateless public class SoyaBeanImpl implements SoyaBean { @PersistenceContext() private EntityManager em; @Override public List getToys() { Query q = em.createQuery("SELECT T from Toys T"); return (List) q.getResultList(); } @Override public void addToy() { Toys newToy = new Toys(); em.persist(newToy); } } 

更新2如果有人能告诉我除了令人不安的方式以外,我能以任何方式实现同​​样的目标,我也非常感激。

最好的祝福,

詹姆斯特兰

假设您的代码中没有重大技术错误,这些错误通常与您所暗示的实体管理器返回的数据状态有关。

Cluprit:数据库?

当然,您可能在底层数据库中遇到缓存问题。 但是,鉴于您对system.out语句的描述,这不太可能。

罪魁祸首:豆子?

更可能的罪魁祸首是查询结果以某种方式缓存在bean中,或者更确切地说,在查询结果集返回值中。 如果您的测试数据库允许脏读,那可能是一个解释。 例如,可以通过使用@Interceptor在任何对getToys()的调用之前刷新查询来检查这一点。

另一个潜在的陷阱:误认为无状态与缓存。

最后:关于无国籍的简短说明。 虽然你是正确的,一般来说,bean的无状态应该导致数据不是陈旧的 – 但情况并非总是如此。 EJB上下文中无状态bean的真正定义是那些bean在应用程序生命周期的过程中不具备状态。

总之,有三种不同的方法可以解决您的问题:

1)确保数据库没有做脏读的任何有趣的事情。 2)测试是否拦截对getToys()的调用,并且运行/validation数据库查询没有问题3)确保你想要的无状态类型实际上是由你的ejb容器实现的。

问题是所有SQL查询的结果都被缓存了。 因此,即使我试图刷新玩具列表,它只收到旧的结果。 我通过将文件persistence.xml中的Shared Cache Mode选项设置为None来解决了这个问题。

我认为根本不使用缓存不是一个好选择。 因此,如果有人能告诉我如何在不关闭缓存的情况下实现相同的结果,我将非常感激。