-
-
Notifications
You must be signed in to change notification settings - Fork 74
Calling getId() on a proxy causes the proxy to initialize #175
Comments
I recommend we configure javassist as default for the moment as it is know to work fine |
We are going to manually switch to javassist and see if it causes any test failures or issues. I'll report back. Digging a little more, the javassist proxy that was being returned by Hibernate had a |
Even with the javassist proxy, if you use the property syntax |
This seems to be manifesting in a much worse way in some cases for us now that we have Grails 4 in production. In cases where we have a domain which extends another domain, we are seeing weird, random class cast exceptions when the proxy is being unwrapped. I say random, because they are hard to reproduce and will go away usually with a server restart (for awhile). It seems like some kind of internal state changes that causes it to start happening.
In this case, we have an object: StorageLocation that extends Location. The code that triggers this exception has a proxy reference to a StorageLocation instance and is calling .id on it (which shouldn't actually unwrap the proxy, but does due to this ticket). That ends up triggering We have no 2nd level caching on any of these objects. It's very hard to reproduce in any small test environment since it seems to depend on some other factors that we can't nail down. |
To work around this, we keep having to use a method like this to access the Id on anything that could be a proxy:
But like I mentioned, these are not always reproducible so they pass our test cases and fail in production. We've probably found 1 per week in production since we've gone live for the last month. |
@longwa what did you figure out here? This is a big blocker for us as there is a huge performance hit across our code to hydrate/initialize the entities on a simple id check.
|
Pretty sure it works just setting the property via |
Just to bump this a bit, this is still a problem even in Grails 5 and using Groovy 3.0.9. To add a bit more urgency, Hibernate is removing support for the Javassist proxy in the next version (according to their warning in the logs) so the workaround will not really be viable. Plus, in Grails 5, we are seeing now that even the Javassist proxy is unwrapping with |
… Javassist collions. uses Hibernate helpers. Mark SimpleHibernateProxyHandler as deprecated. Add tests to show the proxy problems with groovy resolves grails#464 resolves grails#175
@longwa @puneetbehl I added a test here that shows the problem. The recent issue is somewhat related #464.
I made a POC to override the ByteBuddyInterceptor in gorm-tools and its working. Can be seen here https://github.com/yakworks/gorm-tools/tree/dev/gorm-tools/src/main/groovy/gorm/tools/hibernate/proxy With passing tests here. https://github.com/yakworks/gorm-tools/blob/dev/gorm-tools/src/test/groovy/gorm/tools/hibernate/HibernateProxySpec.groovy Going to work on breaking it into it own library so its non invasive and can work with any Groovy/Hibernate use as the problem is not Gorm specific. Will update the branch here with example project once its done. |
added the lib here that I think solves the main issues. https://github.com/yakworks/hibernate-groovy. |
* Upgrade to Liquibase 3.10.1 (also liquibase-hibernate5) - Fixed tests by extracting changeLog part (Gradle verbose log causes polluted outputCapture) - Fixes GroovyChangeLogSpec if default JVM langauge is not en. - String comparisons are now done without spaces in tests - fixes #95 #100 #159 * Use openjdk8 in Travis
GORM 7.0.2.RELEASE
Hibernate 5.4.10.Release
Calling
getId()
orid
on a HibernateProxy causes unwrap. For example, a simple integration test like:Will fail in a default Grails 4 application.
This is because the
getMetaClass
method is called by groovy as part of the method invocation and still cause the unwrap. Previously, GORM had special proxy handling for hibernate's javassist proxies. However, in 5.3, they switched to using ByteBuddy proxies as the default which seem to have broken this behavior.Forcing hibernate to use javassist again via
hibernate.bytecode.provider="javassist"
actually restores the correct behavior and the above test case will pass.I'm not sure what the ramifications for using javassist vs. bytebuddy would be and whether this is a viable workaround.
The better solution might be to implement an extension for Hibernate's byte buddy handler that includes the Groovy friendly logic for ignoring
getMetaClass
orgetStaticMetaClass
, similar to what theorg.grails.datastore.mapping.proxy.JavassistProxyFactory
used to do.The text was updated successfully, but these errors were encountered: