Identity APIs should invalidate cache on update/change of role membership
-------------------------------------------------------------------------
Key: JBPORTAL-1708
URL:
http://jira.jboss.com/jira/browse/JBPORTAL-1708
Project: JBoss Portal
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: Portal Identity
Affects Versions: 2.6.1 Final
Reporter: Andrew Oliver
Consider this code:
String username = request.getParameter("username");
User user= usermodule.findUserByUserName(username);
System.err.println("user was equal to "+(user == null ? "null" :
user.getUserName()));
Role role = rolemodule.findRoleByName("approved");
Set users = new HashSet();
users.add(user);
membership.assignUsers(role, users);
And this code:
Role roleApproved = rolemodule.findRoleByName("approved");
Set usersApproved = membership.getUsers(roleApproved);
With the default Hibernate settings for identity in
server\default\deploy\jboss-portal.sar\conf\hibernate\user\hibernate.cfg.xml:
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>
The second bit of code doesn't see changes by the first bit of code until the portal
is restarted (it seems).
Switching these to false solves the problem. It is likely that this is due to the
HibernateMembershipModuleImpl and the <set
name="roles"
table="jbp_role_membership"
lazy="false"
inverse="false"
cascade="none"
sort="unsorted">
<cache usage="read-write"/>
<key column="jbp_uid"/>
<many-to-many
class="org.jboss.portal.identity.db.HibernateRoleImpl"
column="jbp_rid"
outer-join="true"/>
</set>
which specifies a cached collection and in
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/portal/branches/JBoss_Portal_B...
public void assignRoles(User user, Set roles) throws IdentityException
{
//throw new UnsupportedOperationException("Not yet implemented");
if (!(user instanceof HibernateUserImpl))
{
throw new IllegalArgumentException("User is not a HibernateUserImpl
user");
}
// We make a defensive copy with unwrapped maps and update with a new set
Set copy = new HashSet();
for (Iterator i = roles.iterator(); i.hasNext();)
{
Object o = i.next();
if (o instanceof HibernateRoleImpl)
{
copy.add(o);
}
else
{
throw new IllegalArgumentException("Only HibernateRoleImpl roles can be
accepted");
}
}
// Assign new roles
HibernateUserImpl ui = (HibernateUserImpl)user;
ui.setRoles(copy);
}
The defensive copy which avoids the hibernate collection probably prevents triggering of
the cache invalidation logic in the many-many relationship (not 100% sure that this is how
hibernate works for collection caching but it seems logical).
The hibernate membership module's usage of hibernate is a bit odd and probably needs
review anyhow.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira