6

In my custom authentication provider, I was able to get the domain object through my Service API, but when I crawled from one domain object to another to get certain value to perform additional checks, Spring complains the Hibernate session doesn't exist:-

domain.getAnotherDomain().getProperty(); // epic FAIL

I have the following AOP transaction to wrap all my project APIs with transaction, and I'm pretty sure my custom authentication provider falls into the following pattern:-

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor pointcut="execution(* my.project..*.*(..))" advice-ref="txAdvice" />
</aop:config>

I also have OpenSessionInView filter configured, but I don't think that applies to Spring Security anyway.

I guess I can create a specific Service API to perform all the required checks, but I'm curious why I'm not able to wrap my custom authentication provider with a proper transaction.

Any explanation? Thanks.

limc
  • 39,366
  • 20
  • 100
  • 145

4 Answers4

3

My workaround solution is to create a service API to perform the checks to avoid lazy loading errors in my custom authentication provider.

limc
  • 39,366
  • 20
  • 100
  • 145
1

You haven't posted any code that would let us do any meaningful suggestions.

But one problem with custom authentication provider might be that you maybe marked as @Transactional an abstract method which you are overriding and is being called from the abstract class instance.

For example retreiveUser from AbstractUserDetailsAuthenticationProvider. This method is called from within the instance (see method authenticate) and therefore cannot initialize the transaction through AOP proxy mechanism. For more details check @Transactional method calling another method without @Transactional anotation?

Spring declarative transaction model uses AOP proxy. so the AOP proxy is responsible for creation of the transactions. The AOP proxy will be active only if the methods with in the instance are called from out side the instance.

Community
  • 1
  • 1
JanM
  • 1,385
  • 1
  • 15
  • 25
1

Spring complains the Hibernate session doesn't exist

Not quite sure I follow all your question, but I think the above statement represents your main problem, right? You didn't provide any stacktrace, but I imagine this is the infamous "no session or session closed", typical of the scenario you just described:

domain.getAnotherDomain().getProperty(); // epic FAIL

Maybe I'm missing something, but I think the typical answer would apply here too: map your relationship with fetch=FetchType.EAGER, so that you don't have to lazy load it when the session is already closed.

jpkroehling
  • 13,881
  • 1
  • 37
  • 39
  • The exception message is `failed to lazily initialize a collection of role: ss.domain, no session or session was closed`. I prefer not to perform eager fetching unless absolute necessary... that is, if I get the transaction to wrap the custom authentication provider class. – limc Feb 04 '11 at 17:03
  • Well, if you loaded `domain` in one session, you won't be able to lazily load `anotherDomain` from `domain` in another session. I'm not sure this would be your case, though (it's not clear to me from your question). But you may consider using Fetch Profiles, if you don't want to always do an Eager loading, but you know that sometimes you need. – jpkroehling Feb 04 '11 at 17:06
1

I ran into this same issue, and the cause was that I had Spring Security's filter declared before the OpenSessionInView filter in the web.xml file. Once I swapped them, the problem went away.

The reason is because Spring Security is being called before the Hibernate session is opened by the OpenSessionInView filter, and so there was no session opened.

cdeszaq
  • 30,869
  • 25
  • 117
  • 173