2012-10-27 68 views
0

我目前有工作代碼將孩子保存到父實體。但是我想知道是否我正在做正確的事情,因爲我現在在通過休眠的選擇語句上有重載。我確實使用緩存,所以atm我沒有延遲問題,但我想知道如果我不能更有效率。以這個小提取爲例休眠需要值來保存孩子

MbaLog.debugLog(logger, "Saving CodeType"); 
Site site = codeType.getSite(); 
if (site != null && site.isProxy()) 
    codeType.setSite(siteRepository.loadSiteById(site.getId())); 
Long recordId = codeRepository.saveCodeType(codeType); 

我有一個實體CodeType,我保存有一個子站點。這個孩子被作爲代理對象傳遞給方法,只是它的id被填充。然後我從數據庫中獲取一個完全加載的Site對象並將其設置爲codetype。接下來,我將具有hibernate的sessionfactory的codeType保存到數據庫中(代碼在此處不可見,但位於codeRepository的後面)。

這個工程,但我正在加載一個完整的網站,它有它自己的孩子,所以我看到至少有5個查詢在插入之前傳遞。我可以在網站上放置很多懶惰的東西,但暫時我不會那麼做,因爲在更深層次上可能出現代碼複雜化。我不得不在工作中學習hibernate和JPA,過去從來沒有從專家那裏接受過很多培訓。所以我想知道,是否有一個快捷方式來保存網站的代碼類型?我是否需要將其完全加載或者是否足夠?或只是id和版本(我使用@version註釋上我所有的實體樂觀鎖)提前

回答

1

除了使用Session.get()(或EntityManager.find())去該網站實體的引用的

謝謝,使用Session.load()(或EntityManager.getReference())來獲得此參考。

這些方法將在實體上返回一個延遲加載的代理,而不是執行查詢來獲取網站的數據。

+0

嗯我得到了明顯的印象,使用我的命名查詢通過ID獲取實體是不是要走的路,我應該問問sessionfactory => currentsession =>加載(id),而不是有@NamedQuery (name = Site.QUERY_FIND_BY_ID,query =「from Site where id =:」+ DomainObject.PARAM_ID)? – kenny

+0

是的。這樣的查詢是一個非常糟糕的主意,因爲它會執行Session.get()或EntityManager.find()本身的操作,除了繞過第一級和第二級緩存,使其效率低得多。如果實體已經加載,Session.get()將不會執行任何操作。即使實體已加載,您的命名查詢也會在每次調用時執行查詢。 –

+0

感謝您的解釋,特別是告訴我,它繞過了第一和第二級緩存。我會相應地調整我的代碼。正如我所說,我在旅途中學習了休眠,並在互聯網上提供了教程和文章摘錄。這是非常有用的東西 – kenny

1

如果你想堅持的是Site和CodeType之間的關係,那麼懶惰的實例可能就足夠了。所以你可以使用EntityManager.getReference()(延遲加載)而不是EntityManager.find()

+0

我明白了,事情是我不使用EntityManager,我的所有休眠的東西都通過sessionfactory傳遞給命名查詢。 Query namedQuery = currentSession.getNamedQuery(query);我所有的實體都有一個名爲findById的查詢,我用它們來加載它們。 – kenny

+0

正如@JB Nizet解釋的那樣,使用這種方法可能不是最好的想法。 – rvcoutinho