@Stateful(mappedName = "price") @Singleton @Startup public class PriceManagementBean implements PriceManagement { @PersistenceContext private EntityManager em; private List<PriceStep> priceSteps = Collections.synchronizedList(new ArrayList<PriceStep>()); public PriceManagementBean(){ } @PostConstruct public void init(){ javax.persistence.Query query = em.createQuery("SELECT ps FROM PriceStep ps"); List<PriceStep> res = query.getResultList(); ..... } }
解决方法
Does anybody know,why it does not work in the PostConstruct method?
原因1
你不能同时创建一个@Stateful和@Singleton的bean(嗯,你可以但是因为Singletons也是有状态的,所以没有任何意义),这是你遇到麻烦的原因之一.没有例外,但是那里存在冲突,你需要先解决这个问题.
只记得:
> Singleton bean是一个保持其状态的bean.应用程序中只有一个Singleton实例,它在应用程序的所有用户之间共享.此外,由于它是一个共享(可能更好的并发)bean,因此需要使用@Lock注释实现某种锁定机制.
>有状态bean是一种在交易后保留每个州的bean.在工作时
有状态bean每个用户都获得一个bean的副本,该副本将持续与会话一样长 – 持续或直到调用@Remove注释的方法为止
原因2
即使它有效,您也无法访问结果,因为您将它们存储在一个名为res的对象中,该对象只能从方法init()内部访问.我想你想把返回的值分配给变量priceSteps.
无论如何,你的代码中有很多错误,因为没有说出一切.我不知道你的系统要求是什么,但在这里我会给你一个简单的解决方案,允许你访问数据库:
我想你正试图以某种方式返回bean生命周期中的数据,因为如果bean是@Stateful,你想避免一次又一次地发送查询.
问题是,您不必这样做,您仍然可以使您的bean @Stateless并避免使用许多查询来压缩您的数据库.
你需要做的是创建一个@NamedQuery.
因此,使用@NamedQuery注释您的实体PriceStep,然后输入您编写的查询字符串.在此链接中,您将找到有关如何使用@NamedQueries的信息:
http://docs.oracle.com/cd/B31017_01/web.1013/b28221/ent30qry001.htm
我建议你接下来要注意你的类PriceManagementBean为* @ Stateless *.不要担心,如果在每个请求中创建了一个新的entityManager,它根本不会对数据库造成压力,因为它与域模型交互.
您不需要@PostConstruct,只需在需要时调用@NamedQuery就可以了.应用服务器将缓存它并将其返回给需要它的每个用户,而不是一直与数据库交互.
这里有一个代码:
@Entity @NamedQuery( name="allPriceSteps",queryString="SELECT ps FROM PriceStep ps" ) public class PriceStep implements Serializable { ... }
现在豆子:
@Stateless public class PriceManagementBean implements PriceManagement { @PersistenceContext private EntityManager em; public List<PriceStep> getAllPriceSteps() { Query query = em.createNamedQuery("allPriceSteps"); return query.getResultList(); } }
我希望这很有用.如果您提供有关系统要求的更多信息,我们可以为您提供最佳实践建议.