在我的应用程序中,我有一个@ApplicationScoped
CDI bean来存储数据库中的一些信息:
@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();
}
}
我还有一个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中的玩具列表也根本没有更新。我有另一个带有@RequestScoped
支持bean的ViewToys.xhtml来查看玩具列表,我没有看到列表得到更新。
如果有人能就如何解决这个问题给我建议,我将非常感激。
UPDATE :这是我的SoyaBean实现:
@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);
}
}
更新2 如果有人能告诉我除了令人不安的方式以外,我能以任何方式实现同样的目标,我也非常感激。
致以最诚挚的问候,
James Tran
答案 0 :(得分:0)
假设您的代码中没有重大技术错误,这些错误通常与您所暗示的实体经理返回的数据状态有关。
Cluprit:数据库?
当然,您可能在底层数据库中遇到缓存问题。但是,鉴于您对system.out语句的描述,这不太可能。
罪魁祸首:豆子?
更可能的罪魁祸首是查询结果以某种方式缓存在bean中,或者更确切地说,在查询结果集返回值中。如果您的测试数据库允许脏读,那可能是一个解释。例如,可以通过使用@Interceptor在任何对getToys()的调用之前刷新查询来检查这一点。
另一个潜在的陷阱:误认为无状态与缓存。
最后:关于无国籍的简短说明。虽然你是正确的,一般来说,bean的无状态应该导致数据不是陈旧的 - 但情况并非总是如此。 EJB上下文中无状态bean的真正定义是那些bean在应用程序生命周期的过程中不具备状态。
总之,有三种不同的方法可以解决您的问题:
1)确保数据库在脏读时没有做任何有趣的事情。 2)测试是否拦截对getToys()的调用,并且运行/验证数据库查询没有问题 3)确保您所需的无状态类型实际上是由您的ejb容器实现的。
答案 1 :(得分:0)
问题是所有SQL查询的结果都被缓存了。因此,即使我试图刷新玩具列表,它只收到旧的结果。我通过将文件Shared Cache Mode
中的选项persistence.xml
设置为None
来解决了这个问题。
我认为根本不使用缓存不是一个好选择。因此,如果有人能告诉我如何在不关闭缓存的情况下实现相同的结果,我将非常感激。