2012-04-10 59 views
0

我將當前用戶保存在會話中,當我使用當前用戶(例如:user.getRole.getRoleName())時,我得到了LIE。我怎樣才能解決這個問題,我的代碼是這樣的懶惰初始化在Struts中的Hibernate Spring Hibernate

控制器:

public String home(){ 
    Users users = userService.getCurrentUser(); 
    if(users.getRole().getRoleName().equals("admin")){ //causing LIE 
    .... 
} 

UserService:

@Override 
public Users getCurrentUser(){ 
    session = ActionContext.getContext().getSession(); 
    return (Users) session.get("user"); 
} 

但是,當我改變userService.getCurrentUser()是這樣的,錯誤已解決,但我認爲這不是一種正確的方式,因爲每次使用當前用戶時都需要連接到數據庫。

@Override 
public Users getCurrentUser(){ 
    session = ActionContext.getContext().getSession(); 
    return daoManager.getDetailUser(((Users) session.get("user")).getUsername()); 
} 

DaoManager.getDetailUser是這樣

@Override 
public Users getDetailUser(String username) { 
    try { 
     Users user = (Users)sessionFactory.getCurrentSession().createQuery("SELECT U FROM Users U WHERE U.username=:USERNAME") 
      .setParameter("USERNAME", username) 
      .uniqueResult(); 
     return user; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

有沒有其他更好的辦法來解決這個問題?謝謝。

回答

1

解決這個最簡單的方法是會話關閉之前剛剛訪問懶取指令字段:

@Override 
public Users getCurrentUser(){ 
    session = ActionContext.getContext().getSession(); 
    Users user = (Users) session.get("user"); 
    user.getRole(); //Accessed to resolve lazy field 
    return user; 
} 

我不建議FetchType.EAGER。由於您不能控制訪問,無論您是否需要訪問,它都會被提取。在您的數據模型中添加一些EAGER字段,並突然爲最簡單的請求提取整個數據庫。

對於查詢,您也可以使用JOIN FETCH

+0

同意您不使用FetchType.EAGER,因爲所有數據都將被加載,無論它是否需要。 關於user.getRole();如果我們需要更深層的數據,例如在其他情況下,我們是否會爲每個模型都做到這一點?我很害怕,最終這將會接近FetchType.EAGER。我對嗎? – 2012-04-10 16:36:31

+0

那麼你應該組織你的代碼,以便你只需要獲取在任何情況下你將需要的節點... – barsju 2012-04-10 19:35:41

+0

它不工作(獲得LIE),因爲在沒有打開會話時代碼user.getRole();執行。有沒有其他方法? – 2012-04-12 09:22:33

1

最有可能的解釋是,當你退出服務層(UserService)時,Spring會關閉當前會話,但是在這種情況發生之後,因爲Hibernate試圖延遲加載子對象以避免不必要的加載數據(另請參閱What is lazy loading in Hibernate?)。

爲了避免這種情況,你既可以確保休眠不通過在role指定fetch=FetchType.EAGER做延遲加載,或使用OpenSessionInView模式(然而,這有時被認爲是一個反模式,見Why is Hibernate Open Session in View considered a bad practice?)。

相關問題