2017-03-09 63 views
1

我有這個實體用戶,它有一個角色集合(Set),我想重新緩存,所以無論何時調用getRoles(),它都會返回一個緩存副本。明確加載實體的集合

這裏的結構至今:

  1. User.roles是爲lazy = 「true」,並訪問= 「場」。
  2. User.getRoles()具有一個偵聽器,該偵聽器調用spring @Cacheable方法 ,該方法從redis緩存而不是第二級緩存中檢索。

映射信息:

<set 
      name="roles" 
      table="user_role" 
      lazy="true" 
      cascade="none" 
      access="field" 
     > 
      <key 
       column="user_id" 
      > 
      </key> 
      <many-to-many 
       class="com.resolution.scheduler.model.Role" 
       column="role_id" 
       outer-join="auto" 
      /> 
     </set> 

這裏是GetRoles():

public Set getRoles() { 
     if(!rolesUpdated && this.id!=null){ 
      ApplicationContextProviderNonManageBean.getApplicationContext().publishEvent(
       new com.resolution.scheduler.dao.event.UserRoleGetEvent(this)); 
     } 
       return roles; 
    } 

這裏的時候UserRoleGetEvent事件觸發了所謂:

@Cacheable(value="userRoleByUserId" , key="#userId", condition="#userId!=null") 
    public PersistentSet getUserRoleByUserId(final Long userId){ 
     if(userId==null){ 
      return new PersistentSet(); 
     } 
     log.info("USer Role Getting from Database for User Id : "+userId); 
     //final List<Role> roles=(List<Role>)getHibernateTemplate().find("Select u.roles from User u where u.id=?",userId); 
     final PersistentSet[] set= new PersistentSet[1]; 
     getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Object>(){ 
      public Object doInHibernate(Session session) throws HibernateException{ 
       List roles=session.createQuery("Select u.roles from User u where u.id=:userId").setParameter("userId",userId).list(); 
       set[0]= new PersistentSet((SessionImpl)session, new HashSet(roles)); 
       return null; 
     } 
     }); 
     log.info(set); 

     return set[0]; 
    } 

這裏的UserRoleGetEvent是如何工作的:

public void onApplicationEvent(UserRoleGetEvent event) { 
     PersistentSet roles = userManager.getUserRoleByUserId(event.getUser().getId()); 
     event.getUser().setRoles((roles)); //**THIS_SET_MAKES_IT_DIRTY** 

    } 

問題: 當我做user.getRole(),因爲它爲user.roles設置了一個新的集合,並且會話變得很髒。 在這個骯髒的會話中,每當刷新被稱爲delete全部roles和它insert所有角色再次,即使沒有實際變化。我在尋找的是如何讓hibernate認爲我的新集合像會話檢索(實際上不是這樣)並且不認爲它是骯髒的。

任何解決方法或建議?

+0

類似的問題:http://stackoverflow.com/questions/34763402/proper-cache- spring-hibernate的用法 –

+0

@DraganBozanovic ummm ..不,它與你鏈接的不同,因爲它與加載子關係有關。 –

回答

0

Hibernate不喜歡它的集合被改變。什麼可能的工作是一樣的東西:

event.getUser().getRoles().clear(); 
event.getUser().getRoles().addAll(roles); 

但後來,我有點被你正在嘗試做的困惑。 User上的getRoles觸發事件,然後更改角色?

作爲一個方面說明,我被存儲在這裏工作,但你的代碼可以重構這個:

@Cacheable(value="userRoleByUserId" , key="#userId", condition="#userId!=null") 
public List<Role> getUserRoleByUserId(final Long userId){ 
    if(userId==null){ 
     return Collections.emptyList(); 
    } 
    log.info("USer Role Getting from Database for User Id : "+userId); 

    @SuppressWarning("unchecked") 
    List<Role> result = (List<Role>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Object>(){ 
     public Object doInHibernate(Session session) throws HibernateException{ 
      return session.createQuery("Select u.roles from User u where u.id=:userId").setParameter("userId",userId).list(); 
     } 
    }); 
    log.info(set); 

    return result; 
} 

public void onApplicationEvent(UserRoleGetEvent event) { 
    List<Role> roles = userManager.getUserRoleByUserId(event.getUser().getId()); 
    event.getUser().getRoles().clear(); // yes, I know, getRoles will throw an event and send you in an infinite loop... Fixing that just means having another method 
    event.getUser().getRoles().addAll(roles); 
} 
+0

getRoles()有一個觸發事件,它調用getUserRoleByUserId()。再次調用getRoles()將是stackoverflow。 –

+0

是的。這就是爲什麼我說它會在行評論。只需使用'getRolesThatDontTriggerAnEvent'方法 – Henri

相關問題