[英]EJB: Using EntityManager in PostConstruct method
在構造bean之后,我想使用EntityManager從數據庫中檢索數據。 在構造函數中是不可能的,因為在調用構造函數之后注入EntityManager。 所以我嘗試在用@PostConstruct注釋的方法中做到這一點。 根據API,在完成所有注入后調用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();
.....
}
}
有誰知道,為什么它在PostConstruct方法中不起作用?
原因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();
}
}
我希望這很有用。 如果您提供有關系統要求的更多信息,我們可以為您提供最佳實踐建議。
根據您的要求,請嘗試以下方法
刪除@Stateful [不能同時使用兩者]
@Startup將在APPLICATION INIT期間初始化單例bean [請注意應用程序未完全初始化]。 這可能會在加載EntityManager時引起一些問題,並且我假設EntityManager橋未完全初始化。 嘗試在完成應用程序啟動后調用init [ie,] Remove @Startup
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.