2012-04-10 3 views
0

현재 사용자를 세션에 저장하고 현재 사용자 (예 : user.getRole.getRoleName())를 사용하면 LIE가됩니다.Struts Spring Hibernate에서의 Lazy 초기화 최대 절전 모드

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

UserService : 내가 userService.getCurrentUser를 변경할 때() 이렇게 될

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

하지만, 오류가 난이 문제를 해결할 수있는 방법, 내 코드는이

컨트롤러처럼 나는 현재 사용자를 사용할 때마다 데이터베이스에 연결해야하기 때문에 이것이 올바른 방법이 아니라고 생각합니다.

@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

이 문제를 해결하는 가장 쉬운 방법은 세션이 닫히기 전에 단지 게으른 가져온 필드에 액세스 할 수 있습니다. 그걸로 당신이 액세스를 제어 할 수없는, 그것은 항상 필요하거나하지 가져온다 ... 데이터 모델에 갑자기 몇 가지 EAGER 필드를 추가하고 가장 간단한 요청에 대한 전체 데이터베이스를 가져 오는.

쿼리 들어, JOIN FETCH

+0

은 FetchType.EAGER를 사용하지 않는 것으로 동의합니다. 필요에 따라 모든 데이터가로드되기 때문에 FetchType.EAGER를 사용하지 마십시오. user.getRole()에 관한 ; 우리가 더 자세한 데이터가 필요한 경우, 예를 들어 다른 모델의 경우, 모든 모델에 대해 수행 할 것인지 여부와 같은 경우? 나는 affraid입니다, 궁극적으로 이것은 FetchType.EAGER에 가깝습니다. 내가 맞습니까? –

+0

모든 경우에 필요하게 될 노드 만 가져 오도록 코드를 구성해야합니다 ... – barsju

+0

코드 user.getRole();이 (가) 열려있는 세션이 없으므로 작동하지 않습니다 (LIE를 얻습니다). 실행. 다른 방법이 있습니까? –

1

가장 가능성있는 설명은 서비스 레이어 (UserService)를 종료 할 때 Spring이 현재 세션을 닫을 것이지만, Hibernate가 불필요하게 데이터를로드하는 것을 방지하기 위해 자식 객체를 지연로드하려고 시도하기 때문입니다. What is lazy loading in Hibernate?).

이를 방지하기 위해, 당신은 OpenSessionInView 패턴을 rolefetch=FetchType.EAGER을 지정하여 게으른 로딩을하거나, 사용하지 않는 최대 절전 모드를 확인 할 수 중 하나는 (그러나, 때로는 안티 패턴, Why is Hibernate Open Session in View considered a bad practice?를 참조 간주).

@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을하지 않는 것이 좋습니다 :

관련 문제