Generator-jhipster: Use the Hibernate L2 cache when loading a user

Created on 13 Jul 2017  路  8Comments  路  Source: jhipster/generator-jhipster

This is only for projects using Hibernate with the L2 cache (but that 85% of generated projects!).

Currently, loading the current user uses the user login, for example in UserService.getUserWithAuthorities(). This is used by Spring Security and also when doing a an HTTP GET request on api/account - so this request is in fact quite common.

This is because we use the user's login in Spring Security, and not is ID. This could be discussed, but the idea is that:

  • The login is a "business" name, which could be changed, and can be displayed externally
  • The ID is a "technical key" that should not change, and that should not be displayed externally

So this all looks like a good idea, but as the Hibernate L2 cache uses the ID as the cache key, fetching a user by login means we go outside the cache. And as we usually also want the authorities, we also miss the authorities cache, and do an outer join to get the user+authorities.

This is isn't very good in terms of performance.

My proposal is that:

  • We extend org.springframework.security.core.userdetails.User so we also store the User's ID in the Spring Security thread local object
  • We do a method similar to SecurityUtils.getCurrentUserLogin() but which gets the current user ID (from the extended User in the previous point)

-> we could then get the current user's ID directly, and then use it to get the User, instead of using the login. And that means we would go through the L2 cache, and solve the performance issue.

area

Most helpful comment

OK I'm going to use Spring Cache abstraction for this:

  • It works everywhere, even with MongoDB
  • It shouldn't be too hard to do
  • It shows a good example of Spring Cache, which many people miss when using JHipster

All 8 comments

I've implemented this, as I had similar issues two years ago - and the commits lives on my master branch so I can contribute this.

Oh that's great @gzsombor - I just filled up the ticket so I don't forget this when I'm back from holidays, but if you're ready to do the PR, that's even easier :-)

As login is unique, wouldn't mark login field as a NaturalId(mutable=true) make Hibernate use it as a cache key as well?
They already provide an API for NaturalId fetch.
See documentation NaturalId

@NaturalId is a Hibernate specific annotation, I'm not sure we want to deviate from JPA standard.

Oh I didn't know that NaturalId was cached in L2 - thanks @Blackdread !!!!

  • For me we use JPA unless we require an Hibernate-specific feature. So I have no issue with using this.
  • Of course this needs some testing, but if this gives us automatic L2 cache, then that's less code and issues, and I love it
  • The mutable=true looks like calling for performance issues and/or bugs. The idea with the User entity is that you could change the login (it's the business key, and the ID is the technical key), but I'm not sure we allow that anywhere: maybe we could leave this immutable, and add some documentation in the code, to help people who would like to change this. I need to check this.

Sorry to give bad feedback about the "NaturalId" solution:

  • This is just not supported by Spring Data JPA
  • So this leads to lots of code as you need to implement a specific method that gets the Hibernate session, etc.

So in the end it's not as easy as it looked at the beginning...

OK I'm going to use Spring Cache abstraction for this:

  • It works everywhere, even with MongoDB
  • It shouldn't be too hard to do
  • It shows a good example of Spring Cache, which many people miss when using JHipster

I'm committing the "Spring Cache" solution in the next 5 minutes:

  • This only works when the Hibernate 2nd level cache is selected, for consistency reasons (I guess people who don't want a 2nd level cache don't want any cache at all). So it doesn't work for MongoDB, but that would be trivial to add in the future.
  • It reduces a lot of the SQL requests, so it should speed up many apps.

This of course needs some testing, so that means I won't do a new release too soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Steven-Garcia picture Steven-Garcia  路  3Comments

ahmedeldeeb25 picture ahmedeldeeb25  路  3Comments

tomj0101 picture tomj0101  路  3Comments

marcelinobadin picture marcelinobadin  路  3Comments

frantzynicolas picture frantzynicolas  路  3Comments