在我的应用程序中,我有一个@ApplicationScoped CDI来存储数据库中的一些信息:
@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中的玩具列表根本没有更新。我有另一个ViewToys.xhtml,它有一个@RequestScoped支持bean来查看玩具列表,但是我没有看到列表得到更新。
如果有人能给我一个如何解决这个问题的建议,我将非常感激。
更新:这是我的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);
}
}UPDATE 2,我也非常感谢有人能告诉我,除了我的麻烦之外,我还能以其他任何方式实现相同的目标。
诚挚的问候,
詹姆士·特兰
发布于 2011-12-18 12:29:02
问题是所有SQL查询的结果都被缓存。因此,即使我试图刷新玩具列表,它只收到了旧的结果。我通过将persistence.xml文件中的选项persistence.xml设置为None来解决这个问题。
我认为根本不使用缓存不是一个好的选择。因此,如果有人能告诉我如何在不关闭缓存的情况下实现同样的结果,我将非常感激。
发布于 2011-12-10 11:06:29
假设代码中没有重大技术错误,这些错误通常与实体管理器返回的数据的状态有关,正如您已经暗示的那样。
集群:数据库?
当然,您可能会在基础数据库中出现缓存问题。但是,考虑到您对system.out语句的描述,这是不可能的。
罪魁祸首:豆?
更有可能的罪魁祸首是查询结果以某种方式被缓存在bean中,或者更确切地说,缓存在查询结果集返回值中。如果您的测试数据库允许脏读取,这可能是一个解释。例如,在调用getToys()之前,可以使用@Interceptor刷新查询。
这里的另一个潜在缺陷是:将无国籍状态与缓存相混淆.
最后:关于无国籍状态的简短发言。虽然您是正确的,bean的无状态应该导致,一般来说,数据是不过时的--但情况并不总是如此。EJB上下文中无状态bean的真正定义是,这些bean在应用程序生命周期的过程中不具有状态。
总之,有三种不同的方法可以找到问题的真相:
1)确保数据库没有对脏读做任何有趣的事情。2)测试是否拦截对getToys()的调用,以及运行/验证数据库查询是否没有问题3)确保您想要的无状态类型实际上是由您的ejb容器实现的。
https://stackoverflow.com/questions/8376652
复制相似问题