views:

323

answers:

2

First off, I think I'm trying to use Spring incorrectly, but confirmation would be appreciated.

I am trying to reset a single bean in mid-application. My initial configuration works just fine.

My scenario

  • 1 Insurance Claim bean (session scope)
  • 1 Claim details bean which is a multiactionController (getClaim&setClaim enabled, prototype scope)
  • 1 Claimant details bean which is a multiactionController (getClaim&setClaim enabled, prototype scope)
  • 1 Submit claim bean which is a
    multiactionController
    (getClaim&setClaim enabled, prototype scope).

My application is more complex than this, but for the sake of providing a clear example I wont describe the whole thing.

The first two controllers are used to set various properties of the claim, validate etc.
The third writes a claim to the database. THEN I want it to reset the bean. However I can't just say claim=new Claim() in SubmitClaimController.OnSubmit() as the ApplicationContext keeps its reference to the old Claim.

I could just create a method Claim.clear(), but that feels like the wrong approach. However, I can't see anything like ApplicationContext.destroyBean(beanname) or ApplicationContext.createBean().

I do not want to refresh the entire ApplicationContext as I will have other beans I want to keep alive throughout the session.

Thanks in advance.

+1  A: 

I don't think the Claim object should be Spring-managed. It's really not injected; sounds like it should be bound from the request sent into the controller and passed to the service for processing. If you put a Claim into session scope, you need to invalidate the session when the transaction is done or if the session times out.

By the way, I see you mention three controllers, but no service. You should have a service layer, and controllers should not deal with DAOs or persistence.

duffymo
Thanks for the comment. Couple thoughts >> I have DAOs but am using Controllers to interact with them directly which is poor I suppose. However, the Claim does need to be scoped at the session level, I'm very confident of that. Any way to specifically invalidate just the Claim bean and not the rest of the session?
Knowledgethoughts
If the DAOs aren't getting reference data, I'd say that Controllers should not know about them. The data for the Claim bean should be coming into the controller from the view layer, validated, and bound to a Claim object. Like I said earlier, it's not in the Spring app context, so your question makes no sense in the context in which I know Spring.
duffymo
Agree re: DAOs, put them to one side. A bit of reading makes clear what is needed on that front (i.e. a service layer as you said). However, the Claim object needs to persist on a per-user basis (hence scoping it to the session). I'm not writing to the database right away. It's being cached and could be cancelled at any time. I think AppContext is the wrong term, instead I think it's removing the claim from the session that I am talking about. Is such a thing even possible?I'm probably wording it the wrong way.
Knowledgethoughts
I think that cancelling the Claim that you've currently got in session is nothing more than cleaning out the session and marking it as invalid. All that's clear, the bit that is wrong is thinking that it's under the Spring app context's control. You don't have a claimBean in your app context; you create one each time a user starts a session and binds input values to create a new Claim object. You aren't getting it from the app context is my point.
duffymo
I think I understand but need to test it via debugging only because I've done things strangely. You see, in my applicationcontext.xml I have a ClaimBean scoped and I inject it using a <property> tag. Regardless, you've clarified several things, not least that I need to be looking at the session first. The service tips are helpful as well. It was actually an answer to an earlier question I asked on SO that I had not fully understood. Cheers.
Knowledgethoughts
A: 

You can change the scope of a bean. Default is singleton which is sometimes not appropriate in web contexts. You can change it to be session scoped by adding for example the attribute scope="session" and the child <aop:scoped-proxy proxy-target-class="false"/> to the bean definition.

I am working with 3.0M4, btw, but I would expect it to be in earlier versions, as well, as it's a very important functionality. Have a look at:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch03s05.html

Cheers!

Risadinha