gpt4 book ai didi

java - EJB:在 PostConstruct 方法中使用 EntityManager

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:23:35 25 4
gpt4 key购买 nike

构建 bean 后,我想使用 EntityManager 从数据库中检索数据。在构造函数中是不可能的,因为EntityManager是在调用构造函数之后注入(inject)的。所以我尝试用@PostConstruct 注释的方法来做。根据 API,在完成所有注入(inject)后调用 PostConstruct 方法。执行查询有效,但它总是返回一个空列表。如果我在其他方法中使用相同的查询,它会返回正确的结果。有谁知道,为什么它在 PostConstruct 方法中不起作用?

@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 也是有状态的),这是你遇到麻烦的原因之一。没有异常(exception),但是那里有冲突,你需要先解决这个问题。

请记住:

  • 单例 bean 是一种维护其状态的 bean。一个应用程序中只有一个单例实例,它在应用程序的所有用户之间共享。此外,由于它是一个共享(最好是并发)bean,因此需要使用 @Lock 注释实现某种锁定机制。

  • 有状态的 bean 是一种在事务后维护每个状态的 bean。与
    一起工作时有状态 bean 每个用户都会获得一份 bean 副本,该副本将持续到 session 持续时间 - 持续或直到调用带有 @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 {
...
}

现在是 bean :

@Stateless
public class PriceManagementBean implements PriceManagement {

@PersistenceContext
private EntityManager em;

public List<PriceStep> getAllPriceSteps() {
Query query = em.createNamedQuery("allPriceSteps");
return query.getResultList();
}
}

我希望这是有用的。如果您提供有关系统要求的更多信息,我们可以为您提供有关最佳实践的建议。

关于java - EJB:在 PostConstruct 方法中使用 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10385246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com