-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HIbernate proxies are not unwrapped for lazy fetched inherited domain objects #1468
Comments
See the app at https://github.com/jeffbrown/issue1468. That may help while troubleshooting. grails-app/domain/issue1468/Person.groovy package issue1468
class Person {
String name
boolean isMarried() {
false
}
} grails-app/domain/issue1468/Adult.groovy package issue1468
class Adult extends Person {
boolean isMarried() {
true
}
} grails-app/domain/issue1468/Event.groovy package issue1468
class Event {
Person person
} grails-app/init/issue1468/BootStrap.groovy package issue1468
class BootStrap {
def init = { servletContext ->
new Event(person: new Adult(name: 'Jeff')).save()
}
def destroy = {
}
} grails-app/controllers/issue1468/DemoController.groovy package issue1468
import org.grails.orm.hibernate.cfg.GrailsHibernateUtil
class DemoController {
def index() {
def event = Event.first()
// this works
// render GrailsHibernateUtil.unwrapIfProxy(event.person).isMarried()
// This will throw ClassCastException
render event.person.isMarried()
}
}
|
We've reviewed this issue and have determined that GORM is behaving as expected in this situation. One of the changes in GORM for Hibernate 7, is that it no longer creates custom proxy factories. It also no longer automatically unwraps Hibernate proxies. This change makes the behavior in GORM more consistent with standard Hibernate. While the change was documented in the GORM for Hibernate Upgrade Notes we did find that our documentation needed to be updated regarding this change including guidance for situations where inheritance is involved such as the example in this issue. The updated documentation will be published with the next release of GORM. For the example above, there are two ways to approach this: 1 - If you know in advance that you will be accessing the def event = Event.where { id == 1 }.join("person")[0] 2 - If you are not sure if the association will be used, the proxy can be manually unwrapped by injecting an instance of ProxyHandler. proxyHandler.unwrap(event.person) |
@JasonTypesCodes : I wonder why you prefer exposing the leaky abstraction of hibernate and it's proxies to helping your users by hiding these implementation details? |
Hi, we are working on updating an application from Grails 2.5.6 to Grails 4.0.10 and the automatic unwrapping of proxies seem to no longer work for inherited classes.
This seems to be an old issue which was first reported here, #1072 . It happened because this line was commented.
The issue was fixed with this commit grails/gorm-hibernate5@5c4e6ed
But then it resurfaced, the same line got commented again https://github.com/grails/gorm-hibernate5/blob/9512dbcb91164776acabf128401f235c93b493be/grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java#L2686
Steps to Reproduce
Given the domain classes :
Where
event.person
is a lazy loaded property.Call
event.person.isMarried()
Expected Behaviour
Grails should cast unwrap the Proxy (which wraps an Adult class) before calling the method. This was the actual behavior in
grails 2.5.6
Actual Behaviour
Grails throws
java.lang.ClassCastException: com.aaa.domain.Person$HibernateProxy$fn2kTwKv cannot be cast to com.aaa.domain.Adult
Environment Information
The text was updated successfully, but these errors were encountered: