|
Hi, I have a complex domain object which I want to update
atomically based on a form POST. I still want validation to work, though. I’ve put the update logic in a service so that the
update is transactional. As I understand it, the correct way to indicate that the
changes should be rolled back is to throw a RuntimeException from the service,
so that’s what I do if the changes fail validation. Unfortunately, this seems to close the hibernate Session,
which means that my views can’t access any child collection properties
without a “failed to lazily initialize a collection” exception. Is there anything I can do about this? Can I open a new
session? Can I mark the changes for rollback without closing the session? Is
there a better way to structure this? The controller looks something like: class FooController
{ def
fooRepositoryService def
save { def
foo = Foo.get(params.id) try
{ fooRepositoryService.save(foo,
params) flash.message
= "Changes saved" return redirect(action: "edit", id:
foo.id) } catch (FooRepositoryException e) { render(view: "edit", model:
[questionnaire: questionnaire]) } } } And the service looks something like: class FooRepositoryService
{ def
save(Foo foo, def params) { foo.properties
= params // (real code is more complex here) if
(foo.validate() && foo.save(flush: true)) { return
foo } throw
new FooRepositoryException(“unable to save foo”) } } class FooRepositoryException
extends RuntimeException {} I’m using Grails 1.3.4. Many thanks, Rich softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB |
|
Hi, Does anyone have any suggestions
on this one? Quick summary: Grails has
session-in-view by default, and my views rely on that for lazily loaded
properties. However, after a validation failure inside a Service save() method,
rolling back the spring transaction causes the hibernate session to be closed,
and no new one is automatically opened to replace it. This causes my views to
error when I access lazily loaded properties while displaying the edit page
with validation messages for the user to retry the transaction. How can I re-open the session? Thanks, Rich From: Richard Bradley
[mailto:[hidden email]] Hi, I have a complex domain object which I want to update
atomically based on a form POST. I still want validation to work, though. I’ve put the update logic in a service so that the update is
transactional. As I understand it, the correct way to indicate that the
changes should be rolled back is to throw a RuntimeException from the service,
so that’s what I do if the changes fail validation. Unfortunately, this seems to close the hibernate Session,
which means that my views can’t access any child collection properties without
a “failed to lazily initialize a collection” exception. Is there anything I can do about this? Can I open a new
session? Can I mark the changes for rollback without closing the session? Is
there a better way to structure this? The controller looks something like: class FooController
{
def fooRepositoryService
def save {
def foo = Foo.get(params.id)
try {
fooRepositoryService.save(foo, params)
flash.message = "Changes saved" return redirect(action: "edit", id:
foo.id) } catch (FooRepositoryException e) { render(view: "edit", model:
[questionnaire: questionnaire]) } } } And the service looks something like: class
FooRepositoryService {
def save(Foo foo, def params) {
foo.properties = params // (real code is more complex here)
if (foo.validate() && foo.save(flush: true)) {
return foo
}
throw new FooRepositoryException(“unable to save foo”)
} } class
FooRepositoryException extends RuntimeException {} I’m using Grails 1.3.4. Many thanks, Rich softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB |
|
I can't replicate this using code very similar to what you've shown. I'm getting the same session after the exception as before and it's still open. Create a small project that demonstrates the issue and create a JIRA issue with the project attached (run 'grails bug-report' to generate the project zip) and we'll take a look.
Burt > Hi, > > Does anyone have any suggestions on this one? > > Quick summary: Grails has session-in-view by default, and my views rely on that for lazily loaded properties. However, after a validation failure inside a Service save() method, rolling back the spring transaction causes the hibernate session to be closed, and no new one is automatically opened to replace it. This causes my views to error when I access lazily loaded properties while displaying the edit page with validation messages for the user to retry the transaction. > > How can I re-open the session? > > Thanks, > > > Rich > > > From: Richard Bradley [mailto:[hidden email]] > Sent: 09 September 2010 16:18 > To: [hidden email] > Subject: [grails-user] session closed after a service rolls back / "failed to lazily initialize a collection" > > Hi, > > I have a complex domain object which I want to update atomically based on a form POST. I still want validation to work, though. > I've put the update logic in a service so that the update is transactional. > As I understand it, the correct way to indicate that the changes should be rolled back is to throw a RuntimeException from the service, so that's what I do if the changes fail validation. > Unfortunately, this seems to close the hibernate Session, which means that my views can't access any child collection properties without a "failed to lazily initialize a collection" exception. > > Is there anything I can do about this? Can I open a new session? Can I mark the changes for rollback without closing the session? Is there a better way to structure this? > > The controller looks something like: > > class FooController { > def fooRepositoryService > > def save { > def foo = Foo.get(params.id) > try { > fooRepositoryService.save(foo, params) > flash.message = "Changes saved" > return redirect(action: "edit", id: foo.id) > } catch (FooRepositoryException e) { > render(view: "edit", model: [questionnaire: questionnaire]) > } > } > } > > And the service looks something like: > > class FooRepositoryService { > def save(Foo foo, def params) { > foo.properties = params // (real code is more complex here) > > if (foo.validate() && foo.save(flush: true)) { > return foo > } > throw new FooRepositoryException("unable to save foo") > } > } > > class FooRepositoryException extends RuntimeException {} > > > I'm using Grails 1.3.4. > > Many thanks, > > > Rich > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > |
|
In reply to this post by Richard Bradley
Thanks, Burt, For some reason I didn’t get
your email; I’ve only just found it in the forums. I’ve been able to reproduce this
in a small project. I’ve attached a zip to http://jira.codehaus.org/browse/GRAILS-6743 Thanks for your help, Rich From: Burt Beckwith Sent: Sep 16, 2010 I can't replicate this using code very similar to what you've
shown. I'm getting the same session after the exception as before and it's
still open. Create a small project that demonstrates the issue and create a
JIRA issue with the project attached (run 'grails bug-report' to generate the
project zip) and we'll take a look. softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB From: Richard Bradley
[mailto:[hidden email]] Hi, Does anyone have any suggestions
on this one? Quick summary: Grails has
session-in-view by default, and my views rely on that for lazily loaded properties.
However, after a validation failure inside a Service save() method, rolling
back the spring transaction causes the hibernate session to be closed, and no
new one is automatically opened to replace it. This causes my views to error
when I access lazily loaded properties while displaying the edit page with
validation messages for the user to retry the transaction. How can I re-open the session? Thanks, Rich From: Richard Bradley
[mailto:[hidden email]] Hi, I have a complex domain object which I want to update
atomically based on a form POST. I still want validation to work, though. I’ve put the update logic in a service so that the update is
transactional. As I understand it, the correct way to indicate that the
changes should be rolled back is to throw a RuntimeException from the service,
so that’s what I do if the changes fail validation. Unfortunately, this seems to close the hibernate Session,
which means that my views can’t access any child collection properties without
a “failed to lazily initialize a collection” exception. Is there anything I can do about this? Can I open a new
session? Can I mark the changes for rollback without closing the session? Is
there a better way to structure this? The controller looks something like: class FooController
{
def fooRepositoryService
def save {
def foo = Foo.get(params.id)
try {
fooRepositoryService.save(foo, params)
flash.message = "Changes saved" return redirect(action: "edit", id:
foo.id) } catch (FooRepositoryException e) { render(view: "edit", model:
[questionnaire: questionnaire]) } } } And the service looks something like: class
FooRepositoryService {
def save(Foo foo, def params) {
foo.properties = params // (real code is more complex here)
if (foo.validate() && foo.save(flush: true)) {
return foo
}
throw new FooRepositoryException(“unable to save foo”)
} } class
FooRepositoryException extends RuntimeException {} I’m using Grails 1.3.4. Many thanks, Rich softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB softwire Softwire Technology Limited.
Registered in England no. 3824658. Registered Office : 13 Station Road, London
N3 2SB softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB |
|
Hi, Has anyone had a chance to have
a look at this? I’ve put a repro case on JIRA at http://jira.codehaus.org/browse/GRAILS-6743 Quick summary: Grails has
session-in-view by default, and my views rely on that for lazily loaded
properties. However, after a validation failure inside a Service save() method,
rolling back the spring transaction causes the hibernate session to be closed,
and no new one is automatically opened to replace it. This causes my views to
error when I access lazily loaded properties while displaying the edit page
with validation messages for the user to retry the transaction. How can I re-open the session? Thanks, Rich softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB From: Richard Bradley
[mailto:[hidden email]] Thanks, Burt, For some reason I didn’t get
your email; I’ve only just found it in the forums. I’ve been able to reproduce this
in a small project. I’ve attached a zip to http://jira.codehaus.org/browse/GRAILS-6743 Thanks for your help, Rich From: Burt Beckwith Sent: Sep 16, 2010 I can't replicate this using code very similar to what you've
shown. I'm getting the same session after the exception as before and it's still
open. Create a small project that demonstrates the issue and create a JIRA
issue with the project attached (run 'grails bug-report' to generate the
project zip) and we'll take a look. softwire Softwire Technology Limited.
Registered in England no. 3824658. Registered Office : 13 Station Road, London
N3 2SB From: Richard Bradley
[mailto:[hidden email]] Hi, Does anyone have any suggestions
on this one? Quick summary: Grails has
session-in-view by default, and my views rely on that for lazily loaded
properties. However, after a validation failure inside a Service save() method,
rolling back the spring transaction causes the hibernate session to be closed,
and no new one is automatically opened to replace it. This causes my views to
error when I access lazily loaded properties while displaying the edit page
with validation messages for the user to retry the transaction. How can I re-open the session? Thanks, Rich From: Richard Bradley [mailto:[hidden email]]
Hi, I have a complex domain object which I want to update
atomically based on a form POST. I still want validation to work, though. I’ve put the update logic in a service so that the update is
transactional. As I understand it, the correct way to indicate that the
changes should be rolled back is to throw a RuntimeException from the service,
so that’s what I do if the changes fail validation. Unfortunately, this seems to close the hibernate Session,
which means that my views can’t access any child collection properties without
a “failed to lazily initialize a collection” exception. Is there anything I can do about this? Can I open a new
session? Can I mark the changes for rollback without closing the session? Is
there a better way to structure this? The controller looks something like: class FooController
{
def fooRepositoryService
def save {
def foo = Foo.get(params.id)
try {
fooRepositoryService.save(foo, params)
flash.message = "Changes saved" return redirect(action: "edit", id:
foo.id) } catch (FooRepositoryException e) { render(view: "edit", model:
[questionnaire: questionnaire]) } } } And the service looks something like: class
FooRepositoryService {
def save(Foo foo, def params) {
foo.properties = params // (real code is more complex here)
if (foo.validate() && foo.save(flush: true)) {
return foo
}
throw new FooRepositoryException(“unable to save foo”)
} } class
FooRepositoryException extends RuntimeException {} I’m using Grails 1.3.4. Many thanks, Rich softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB softwire Softwire Technology Limited. Registered
in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB softwire Softwire Technology Limited.
Registered in England no. 3824658. Registered Office : 13 Station Road, London
N3 2SB softwire Softwire
Technology Limited. Registered in England no. 3824658. Registered Office : 13
Station Road, London N3 2SB |
|
Sorry, I meant to look at that but haven't yet. I think what's happening is that the session is open but the object is detached from it. This was added a while back so when validation fails, the object is detached so its changes don't get persisted.
If you have a problem with an application-level constraint that doesn't have a corresponding database constraint (e.g. inList or blank, but not nullable/unique/etc.) then because of the Open Session In View interceptor, if the instance isn't detatched then since it's dirty its changes get pushed by Hibernate and since there's no problem at the database level it succeeds, causing unexpected updates. So the sensible fix is to detach it to keep that from happening. But in your case since the collection isn't initialized before validation, once it's detached it will blow up when referenced from the GSP. One fix would be to initialize the collection before validation. This makes sense if you know you'll be displaying the collection regardless, but it's a little expensive otherwise. Burt > Hi, > > Has anyone had a chance to have a look at this? I've put a repro case on JIRA at http://jira.codehaus.org/browse/GRAILS-6743 > > Quick summary: Grails has session-in-view by default, and my views rely on that for lazily loaded properties. However, after a validation failure inside a Service save() method, rolling back the spring transaction causes the hibernate session to be closed, and no new one is automatically opened to replace it. This causes my views to error when I access lazily loaded properties while displaying the edit page with validation messages for the user to retry the transaction. > > How can I re-open the session? > > Thanks, > > > Rich > > > > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > From: Richard Bradley [mailto:[hidden email]] > Sent: 20 September 2010 18:29 > To: [hidden email] > Subject: [grails-user] RE: session closed after a service rolls back / "failed to lazily initialize a collection" > > Thanks, Burt, > > For some reason I didn't get your email; I've only just found it in the forums. > > I've been able to reproduce this in a small project. > > I've attached a zip to http://jira.codehaus.org/browse/GRAILS-6743 > > Thanks for your help, > > > Rich > > > From: Burt Beckwith > Sent: Sep 16, 2010 > > I can't replicate this using code very similar to what you've shown. I'm getting the same session after the exception as before and it's still open. Create a small project that demonstrates the issue and create a JIRA issue with the project attached (run 'grails bug-report' to generate the project zip) and we'll take a look. > > Burt > > > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > From: Richard Bradley [mailto:[hidden email]] > Sent: 16 September 2010 14:15 > To: [hidden email] > Subject: [grails-user] RE: session closed after a service rolls back / "failed to lazily initialize a collection" > > Hi, > > Does anyone have any suggestions on this one? > > Quick summary: Grails has session-in-view by default, and my views rely on that for lazily loaded properties. However, after a validation failure inside a Service save() method, rolling back the spring transaction causes the hibernate session to be closed, and no new one is automatically opened to replace it. This causes my views to error when I access lazily loaded properties while displaying the edit page with validation messages for the user to retry the transaction. > > How can I re-open the session? > > Thanks, > > > Rich > > > From: Richard Bradley [mailto:[hidden email]] > Sent: 09 September 2010 16:18 > To: [hidden email] > Subject: [grails-user] session closed after a service rolls back / "failed to lazily initialize a collection" > > Hi, > > I have a complex domain object which I want to update atomically based on a form POST. I still want validation to work, though. > I've put the update logic in a service so that the update is transactional. > As I understand it, the correct way to indicate that the changes should be rolled back is to throw a RuntimeException from the service, so that's what I do if the changes fail validation. > Unfortunately, this seems to close the hibernate Session, which means that my views can't access any child collection properties without a "failed to lazily initialize a collection" exception. > > Is there anything I can do about this? Can I open a new session? Can I mark the changes for rollback without closing the session? Is there a better way to structure this? > > The controller looks something like: > > class FooController { > def fooRepositoryService > > def save { > def foo = Foo.get(params.id) > try { > fooRepositoryService.save(foo, params) > flash.message = "Changes saved" > return redirect(action: "edit", id: foo.id) > } catch (FooRepositoryException e) { > render(view: "edit", model: [questionnaire: questionnaire]) > } > } > } > > And the service looks something like: > > class FooRepositoryService { > def save(Foo foo, def params) { > foo.properties = params // (real code is more complex here) > > if (foo.validate() && foo.save(flush: true)) { > return foo > } > throw new FooRepositoryException("unable to save foo") > } > } > > class FooRepositoryException extends RuntimeException {} > > > I'm using Grails 1.3.4. > > Many thanks, > > > Rich > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Thanks, that would be great.
You're right, the only current fix is to manually initialize the collection during validation. That's what I'm doing now. This seems problematic to me because it means that my services have to "know" which collections will be required by the views on validation failure, which breaks encapsulation, and it means that if I fail to correctly identify which collections will be needed, I'll get 500 errors during validation, so it's fragile. My services currently look something like: class ComplexModelRepositoryService { def save(ComplexModel complexModel, def params) { ... update complexModel here ... if (complexModel.validate()) { if (complexModel.save(flush: true)) { return complexModel } } else { // FIXME:see http://jira.codehaus.org/browse/GRAILS-6743 [complexModel.someProperty, complexModel.otherProperty].each { it?.someCollection?.each { Hibernate.initialize(it.yetAnotherCollection) } } } // set the id back to 0 for currently saved complexModels which are about to // become transient again when this transaction is rolled back: if (complexModelWasSavedDuringThisTransaction) { complexModel.id = null } throw new ComplexModelRepositoryException("unable to save complexModel") } } -----Original Message----- From: Burt Beckwith [mailto:[hidden email]] Sent: 28 September 2010 21:20 To: [hidden email] Subject: Re: [grails-user] RE: session closed after a service rolls back / "failed to lazily initialize a collection" Sorry, I meant to look at that but haven't yet. I think what's happening is that the session is open but the object is detached from it. This was added a while back so when validation fails, the object is detached so its changes don't get persisted. If you have a problem with an application-level constraint that doesn't have a corresponding database constraint (e.g. inList or blank, but not nullable/unique/etc.) then because of the Open Session In View interceptor, if the instance isn't detatched then since it's dirty its changes get pushed by Hibernate and since there's no problem at the database level it succeeds, causing unexpected updates. So the sensible fix is to detach it to keep that from happening. But in your case since the collection isn't initialized before validation, once it's detached it will blow up when referenced from the GSP. One fix would be to initialize the collection before validation. This makes sense if you know you'll be displaying the collection regardless, but it's a little expensive otherwise. Burt > Hi, > > Has anyone had a chance to have a look at this? I've put a repro case on JIRA at http://jira.codehaus.org/browse/GRAILS-6743 > > Quick summary: Grails has session-in-view by default, and my views rely on that for lazily loaded properties. However, after a validation failure inside a Service save() method, rolling back the spring transaction causes the hibernate session to be closed, and no new one is automatically opened to replace it. This causes my views to error when I access lazily loaded properties while displaying the edit page with validation messages for the user to retry the transaction. > > How can I re-open the session? > > Thanks, > > > Rich > > > > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > From: Richard Bradley [mailto:[hidden email]] > Sent: 20 September 2010 18:29 > To: [hidden email] > Subject: [grails-user] RE: session closed after a service rolls back / "failed to lazily initialize a collection" > > Thanks, Burt, > > For some reason I didn't get your email; I've only just found it in the forums. > > I've been able to reproduce this in a small project. > > I've attached a zip to http://jira.codehaus.org/browse/GRAILS-6743 > > Thanks for your help, > > > Rich > > > From: Burt Beckwith > Sent: Sep 16, 2010 > > I can't replicate this using code very similar to what you've shown. I'm getting the same session after the exception as before and it's still open. Create a small project that demonstrates the issue and create a JIRA issue with the project attached (run 'grails bug-report' to generate the project zip) and we'll take a look. > > Burt > > > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > From: Richard Bradley [mailto:[hidden email]] > Sent: 16 September 2010 14:15 > To: [hidden email] > Subject: [grails-user] RE: session closed after a service rolls back / "failed to lazily initialize a collection" > > Hi, > > Does anyone have any suggestions on this one? > > Quick summary: Grails has session-in-view by default, and my views rely on that for lazily loaded properties. However, after a validation failure inside a Service save() method, rolling back the spring transaction causes the hibernate session to be closed, and no new one is automatically opened to replace it. This causes my views to error when I access lazily loaded properties while displaying the edit page with validation messages for the user to retry the transaction. > > How can I re-open the session? > > Thanks, > > > Rich > > > From: Richard Bradley [mailto:[hidden email]] > Sent: 09 September 2010 16:18 > To: [hidden email] > Subject: [grails-user] session closed after a service rolls back / "failed to lazily initialize a collection" > > Hi, > > I have a complex domain object which I want to update atomically based on a form POST. I still want validation to work, though. > I've put the update logic in a service so that the update is transactional. > As I understand it, the correct way to indicate that the changes should be rolled back is to throw a RuntimeException from the service, so that's what I do if the changes fail validation. > Unfortunately, this seems to close the hibernate Session, which means that my views can't access any child collection properties without a "failed to lazily initialize a collection" exception. > > Is there anything I can do about this? Can I open a new session? Can I mark the changes for rollback without closing the session? Is there a better way to structure this? > > The controller looks something like: > > class FooController { > def fooRepositoryService > > def save { > def foo = Foo.get(params.id) > try { > fooRepositoryService.save(foo, params) > flash.message = "Changes saved" > return redirect(action: "edit", id: foo.id) > } catch (FooRepositoryException e) { > render(view: "edit", model: [questionnaire: questionnaire]) > } > } > } > > And the service looks something like: > > class FooRepositoryService { > def save(Foo foo, def params) { > foo.properties = params // (real code is more complex here) > > if (foo.validate() && foo.save(flush: true)) { > return foo > } > throw new FooRepositoryException("unable to save foo") > } > } > > class FooRepositoryException extends RuntimeException {} > > > I'm using Grails 1.3.4. > > Many thanks, > > > Rich > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com<http://www.softwire.com/> | E-mail : [hidden email] <mailto:[hidden email]> > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email softwire Richard Bradley Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 Web : www.softwire.com | E-mail : [hidden email] Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by burtbeckwith
Does anyone have any further suggestions on this thread?
http://grails.1312388.n4.nabble.com/session-closed-after-a-service-rolls-back-failed-to-lazily-initialize-a-collection-td2533057.html Basically, we've been putting all our databinding + saving logic inside services, so that we have transactionality. This works well, except that on validation failure, rolling back the transaction from within a service causes the Hibernate session to be closed. This means that all our views which rely on open-session-in-view to display child collections will throw errors when trying to redisplay the model after a validation failure, unless we manually initialise the model in the session before throwing an exception. I'm actually a bit surprised that no-one else has this issue. * Is it uncommon to use services for saving changes from a user form? If so, how do others enforce transactionality of user form changes? * Maybe it is uncommon to have views which display child collections on validation failure? Does this mean that my models are too complex? We seem to have a great many pages which have this problem. * Perhaps others avoid this issue by using Command objects which do validation outside of a service, so by the time the data gets to the service, you know that you can't have a validation failure? There's an example project which demonstrates the issue at http://jira.codehaus.org/browse/GRAILS-6743 Thanks, Rich softwire Richard Bradley Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 Web : www.softwire.com | E-mail : [hidden email] Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
It doesn't cause the session to be closed, it causes the invalid instance to be discarded, which disconnects it from the session. The current best option seems to be to initialize the collections before validating if you plan on accessing the collections from a GSP.
Burt > Does anyone have any further suggestions on this thread? > > http://grails.1312388.n4.nabble.com/session-closed-after-a-service-rolls-back-failed-to-lazily-initialize-a-collection-td2533057.html > > Basically, we've been putting all our databinding + saving logic inside services, so that we have transactionality. This works well, except that on validation failure, rolling back the transaction from within a service causes the Hibernate session to be closed. > > This means that all our views which rely on open-session-in-view to display child collections will throw errors when trying to redisplay the model after a validation failure, unless we manually initialise the model in the session before throwing an exception. > > I'm actually a bit surprised that no-one else has this issue. > > * Is it uncommon to use services for saving changes from a user form? If so, how do others enforce transactionality of user form changes? > * Maybe it is uncommon to have views which display child collections on validation failure? Does this mean that my models are too complex? We seem to have a great many pages which have this problem. > * Perhaps others avoid this issue by using Command objects which do validation outside of a service, so by the time the data gets to the service, you know that you can't have a validation failure? > > There's an example project which demonstrates the issue at http://jira.codehaus.org/browse/GRAILS-6743 > > Thanks, > > > Rich > > > softwire > Richard Bradley > Tel : 020 7485 7500 ext 230 | Fax : 020 7485 7575 > Web : www.softwire.com | E-mail : [hidden email] > Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > > Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
This post has NOT been accepted by the mailing list yet.
I'm just replying to this old thread to say that the issue has been fixed in grails.
See https://github.com/grails/grails-doc/commit/253a59050e12b69b84084e985f28e3a0eca39d62 for full details, including several possible options for working around the problem. Thanks all, Rich |
| Powered by Nabble | Edit this page |
