Database-sessions in Spring

2019-07-29 06:41发布

问题:

I'm quite new to Spring, and I would like to understand a bit more about sessions. I've mapped a legacy database with Hibernate annotated entities and built a couple of service objects to fetch, retrieve etc. My entities also contain other entities (mapped through foreign keys) and sets of entities. When I traverse the entitiy graph in my services, I have no problem. My services been wrapped in a TransactionProxyFactoryBean, so all should be good.

So, in my View Controller I request a bunch of entities from the services. But when I traverse the entity graph in my view controller (for example to display user's state's country's name, with both state and country being lazily loaded entities), the Hibernate session is already closed and I get a "LazyInitializationException: could not initialize proxy - no Session"

I wouldn't want my services to eagerly fetch the data, that'll consume way to much RAM because my graphs are deep and can even have circular references. I also don't want to explicitly have to touch on the parts that I'll be displaying in the services, as that'd mean that I'll have to copy/paste write similar services over and over again. So what I want is to have the Hibernate session still open when I'm in my view controller and not close down the session until the view has been served. What can I do to keep it open?

My view bean looks like this, is there any way I can inject my TransactionProxyFactoryBean-derived bean into it?

  <bean name="/" class="example.SimpleViewController">
    <property name="userService" ref="userService"/>
    <property name="catalogService" ref="catalogService"/>
  </bean>

Cheers

Nik

回答1:

See my answer to this question: In Spring with jpa/hibernate, how do I keep a session open to avoid lazy initialization exceptions?

I'm using Hibernate without Spring, so I am not 100% sure of the capabilities Spring has to deal with Sessions, but I believe it has both a built in Filter and Interceptor. The best way to handle sessions outside of JPA is to write a filter that opens the session before handing off to the rest of your server side stuff, then closes the session afterwards. I believe this is what Spring's built in stuff does.



回答2:

You still have to use the open-session-in-view pattern to avoid this particular problem, regardless of whether you're using Spring; although Spring has some facility to help with implementing the design pattern on some frameworks like Struts or plain JSP.