Archive for October, 2009

Fixing the User/Role Many-to-Many in the Grails Spring Security Plugin

Sunday, October 25th, 2009

The User/Role many-to-many relationship in the Grails Spring Security plugin is modeled using the standard GORM mapping approach, i.e. using hasMany and belongsTo. As I pointed out here this is a performance concern when you have a large number of users, since granting a new user a popular role (e.g. ROLE_USER) will cause all other users with that role to be loaded from the database.

To fix this in the current plugin would be a breaking change, but I’m planning on creating a new plugin that will use Spring Security 3 once it’s released, so I thought I’d write up some notes on how to fix the many-to-many mapping for current users. It’s only a few steps.

The first is to map the join table, so you’ll need to create a UserRole domain class (I’m assuming that your person class is named User and your authority class is named Role – translate as appropriate):

import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

   User user
   Role role

   boolean equals(other) {
      if (!(other instanceof UserRole)) {
         return false
      }

      return other.user.id == user.id && other.role.id == role.id
   }

   int hashCode() {
      return new HashCodeBuilder().append(user.id).append(role.id).toHashCode()
   }

   static UserRole create(User user, Role role, boolean flush = false) {
      new UserRole(user: user, role: role).save(flush: flush, insert: true)
   }

   static boolean remove(User user, Role role, boolean flush = false) {
      UserRole userRole = UserRole.findByUserAndRole(user, role)
      return userRole ? userRole.delete(flush: flush) : false
   }

   static void removeAll(User user) {
      executeUpdate("DELETE FROM UserRole WHERE user=:user", [user: user])
   }

   static mapping = {
      id composite: ['role', 'user']
      version false
      table 'role_people'
   }
}

Some notes on this class:

  • it has to implement Serializable since it’s a Hibernate composite primary key class
  • the mapping block settings ensure that the table DDL is the same as that for the autogenerated join table, so you won’t need to update your database
  • the hashCode and equals methods are just suggestions; feel free to re-implement

Next remove static hasMany = [people: User] from Role and static hasMany = [authorities: Role] and static belongsTo = Role from User.

While we don’t want to map the Role’s User collection, we still need convenient access to the User’s roles, so next add a utility method to User to mimic what we removed when deleting the hasMany. While we’re here let’s add a hasRole method:

Set<Role> getAuthorities() {
   UserRole.findAllByUser(this).collect { it.role } as Set
}

boolean hasRole(Role role) {
   UserRole.countByUserAndRole(this, role) > 0
}

If you’re using the plugin-generated CRUD pages (created via grails generate-manager) you’ll want to remove the User listings from views/role/show.gsp:

<tr class="prop">
   <td valign="top" class="name">People:</td>
   <td valign="top" class="value">${authority.people}</td>
</tr>

and views/role/edit.gsp:

<tr class="prop">
  <td valign="top" class="name"><label for="people">People:</label></td>
  <td valign="top" class="value ${hasErrors(bean:authority,field:'people','errors')}">
  <ul>
  <g :each var="p" in="${authority.people?}">
     <li>${p}</li>
  </g>
  </ul>
  </td>
</tr>

Then in RegisterController.groovy change

role.addToPeople(person)

to

UserRole.create(person, role)

and finally in UserController.groovy, change (in two places)

Role.findAll().each { it.removeFromPeople(person) }

to

UserRole.removeAll(person)

and

Role.findByAuthority(key).addToPeople(person)

to

UserRole.create(person, Role.findByAuthority(key))

And that’s it. You shouldn’t need to make any database changes, since the new code will map to the existing tables just like the old code. If you’ve used the addToPeople and removeFromPeople dynamic many-to-many methods elsewhere in your code you’ll need to convert those to use the UserRole helper methods, but otherwise the impact should be fairly minor.

SpringOne/2GX

Saturday, October 24th, 2009

I got back from Spring One/2GX in New Orleans a couple of days ago and wanted to write up some thoughts about what a great time it was. This was my first SpringOne – my first attempt at getting sent by my employer didn’t go so well and I didn’t go to the Groovy/Grails Experience in Reston, VA in 2008. But earlier this year I noticed Guillaume Laforge’s tweet announcing the presentation request page so I submitted 5 Grails proposals, and luckily 4 were selected.

I got into New Orleans around 1:30 on Monday and took a cab to the hotel. When I checked in the clerk smiled and told me I’d been upgraded to a very nice room. She wasn’t kidding, it was huge. As a geek all I need is a bed and a shower (and of course wifi and power for the laptop) but it was cool that the organizers got the speakers such nice rooms.

I went to registration to get my speaker badge and schedule and met Dave Klein, the first of many famous GR8 folks that I met this week. After that I went out wandering and ended up on Bourbon St. Even at 3pm on a Monday it was pretty wild, lots of people and great music. Later on was dinner and then Rod Johnson’s keynote. Of course the highlight for us Grails folks was Graeme’s demo of STS 2.2 with Grails support. After the keynote a bunch of us went to Bourbon St. and had some beers.


My first session of the conference was my Clustering a Grails Application for Scalability and Availability talk. They’d assigned talks to the various rooms based on expected attendance but based on responses from the attendee questionnaire they moved some talks and mine got moved to a larger room, so there was a little confusion there. I’d given an earlier version of this talk at the Boston Grails meetup so it was a good one to do first. It went pretty well and the audience asked lots of great questions. Unfortunately although I discussed two Quartz bugs that need to be fixed, I only fixed one, so the demo crashed with an error that wasn’t very obvious, so I wasn’t able to get that fixed. Of course 5 minutes after the talk I realized what I’d forgotten.

Next up was Hamlet D’Arcy’s Groovy Compiler Metaprogramming and AST Transformations. AST transforms are a powerful addition to Groovy but it’s a complex topic and Hamlet did a great job explaining the concepts. The AST viewer that he wrote is pretty slick. I’ve got a couple of potential uses for ASTs that I’ll be trying out in the next few weeks.

After lunch was my UI Performance – Maximizing Page Load Efficiency talk. This one surprised me. I’m not a UI guy, but I am a performance nut and I’m psyched about what the UI Performance plugin provides to Grails applications. But I was concerned about running under for this talk since this isn’t really an area of expertise for me. However we had a great interactive discussion with lots of great audience questions and this talk was ironically probably the best of the four that I did.

After that was Andy Clement’s Eclipse Groovy Tooling. I’m a hardcore Eclipse user and had been using the v1 Eclipse Groovy plugin. The work that Andy Clement and Andrew Eisenberg have done with the v2 plugin has been fantastic. I’m subscribed to the
eclipse-plugin-user and eclipse-plugin-dev mailing lists so I’m aware of a lot of what’s happened along the way but it was great to hear the stories and challenges from the source.

The last session of the day was Ken Sipe’s Grails and the JVM Memory Management. I’m comfortable with garbage collection and the various heap generations so I didn’t get much out of the first part of Ken’s talk but the demos of VisualVM and BTrace were great. It’s always good to add new tools to the toolkit and these look great.

I got Thai takeout for dinner and skipped Adrian Colyer’s technical keynote to do prep for the next day’s talk but went to the Grails BOF. It was a lively discussion with Graeme and Jeff – you can listen to a recording that Colin Harrington tweeted here.


The first talk Wednesday was Andres Almiray’s Flying with Griffon. I’m a big fan of Griffon, having done a bunch of Swing development. Pretty much everything I do currently is web-based but I’m looking for an excuse to write a desktop app in Griffon and after seeing Andres’ talk I’m even more psyched. The highlight of the talk was finding out that the slick presentation that he’d switched to from his PowerPoint slides was actually a Griffon app: Griffon Talk. btw – I highly recommend Griffon in Action – it’s available in Manning’s early access program and is already packed with great information.

Next was Matt Taylor’s GrailsUI Primer. Being a bad UI developer I need good tools for UI work and GrailsUI is very good. Matt also suggested that it’d be good to integrate GrailsUI with the UI Performance plugin, so that should be interesting.

After lunch was my Advanced GORM – Performance, Customization and Monitoring talk. When I did an earlier version of this talk at the Boston Grails meetup it ran long and I didn’t get to the demo of the graphics and monitoring part, so I rushed this one a bit. But overall the audience seemed to find the content interesting. I even had some people offer to help making the monitoring stuff into a plugin – please email me if you were one of them.

Next was my one Spring talk, Chris Richardson’s Running Java and Grails applications on the Amazon Elastic Compute Cloud. I’ll be working on a project that will deploy to EC2 so this is useful info, but to be honest I was more than a little distracted since they had just announced that STS 2.2 was released so I spent a lot of the talk trying that out.

The final talk of the day was Paul King’s Groovy and Concurrency talk. This was an interesting discussion of the various options for multithreading in Groovy, from Ant’s parallel task to various wrappers of the java.util.concurrent classes like Jetlang and GPars, and the new Fork/Join stuff that’ll be in Java 7.

That night I had dinner with Calen and Chelle from Orange and Bronze. I’ll be working on an outsourcing project with them and they had a booth at the conference, so it was a good opportunity to talk with them in person. The restaurant was at the other end of the French Quarter so we had plenty of time to talk – if the rest of the company is like Calen and Chelle we’ll be in good hands.


I did some prep work for the next day’s Demystifying Spring Security in Grails talk and got to bed reasonably early, but for some reason didn’t set an alarm. Luckily a friend who noticed that I wasn’t available on IM called me at 8am so I at least had 1/2 hour to take a shower and get ready. I didn’t have any caffeine or breakfast and was pretty annoyed at myself for nearly screwing up in a major way, but like the rest of the talks I got plenty of great questions and participation from the audience so except for yet another partially failed demo things went well.

I had another celebrity sighting on the way to the talk: Luke Taylor, who’s currently doing most of the work on Spring Security now that Ben Alex is working on Roo. We talked briefly about the breaking changes in Spring Security 3 that are prompting me to write a new plugin (this will be a great opportunity to start from scratch and also modularize the plugin btw) and he offered to answer questions, so I’ll definitely be taking him up on that offer. Later I ran into Luke and Ben in the hotel coffee shop when I was finally able to get caught up on caffeine and I talked to Ben about Roo – he’s clearly excited about the enthusiasm that people have shown for Roo so far. I doubt I’ll do much with Roo since I’ve spent so much time working with Grails, but I can see how Java developers who like the idea of Convention over Configuration but aren’t ready to make the leap to the dynamic language-based Grails would find Roo attractive.

I was going to go to Ramnivas Laddad’s AOP talk next, but I needed to check out and hadn’t had a chance to pack since I’d overslept, so I did that and spent some time catching up on email. I got a takeout falafel wrap from a funky little Middle Eastern place near the hotel and spent some time working on parallelizing Grails integration tests (inspired by a thread on the Grails user mailing list and Paul King’s talk). It’s mostly finished; once I get it working I’ll post the code and a writeup – it should help speed up test time on multicore machines.

My last talk of the conference was Scott Vlaminck’s AOP in Grails. I had heard about Scott’s Circuit Breaker Plugin but didn’t read enough about it to see how it’d be useful. So I was glad I went to the talk – this plugin is a great idea. We have a Log4j SMTP appender configured on a project and on two occasions recently have generated over 2000 error emails in under an hour, so a circuit breaker would have come in very handy there. Most of the time in Grails we can just use MOP for before/around/after advice, but “real” AOP is necessary when Java is calling Java since there isn’t a hook for MOP.


So it was a fantastic 3 1/2 days. It was cool to meet so many people that I had previously only known online, both the big names in the Groovy/Grails/Griffon communities but also developers, plugin authors, and other users and fans of the GR8 stack.

I’ll be posting the presentations and sample apps for the talks that I did when I get a chance so people can try them out and hopefully take advantage of some of the code.

I’m definitely psyched for next year, and I’m also looking forward to the next GR8 event, the Groovy & Grails Exchange in London in December. After that I’ll be headed to the Philippines in January to work with Orange and Bronze and speak at a Spring and Grails conference that they’re sponsoring, so it’ll be an interesting few months.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.