As we start to move more and more to asynchronous programming models, I'm finding that Grails is WAY too eager about wanting to unwrap proxies, to the point of making them almost unusable in many cases.
For instance, given this scenario where a book is loaded in a different session (imagine the books are loaded in a thread, for instance):
Book book = null
Book.withNewSession {
book = Book.get(1L)
}
Calling:
or even just doing something like:
new Book(author: book.author).save()
Causes a lazy initialization exception, even though nothing but the "id" of the Author is ever needed for this. I mean, if you can't even access the id of a proxy, what good is it?
The problem is that HibernateUtils.handleLazyProxy() is being invoked when "book.author" is called and wants to unwrap the author to "avoid proxy hell" as the comment says.
This example would work just fine without "avoiding proxy hell" and actually prevents the use of concurrent reader threads for batch processing or just simple asynchronous retrieval of related objects for other operations.
Is there some good reason (other than proxy hell, whatever that means) why handleLazyProxy() is so aggressive? Is there some way to disable this on a case-by-case basis?
We have a scenario where we are loading thousands or records in multiple concurrent threads and then want to pass those along to something that is inserting data in multiple threads. We have to eagerly fetch all of the associated objects even though they are just being assigned across such as "a.someProperty = b.someProperty" with no actually use of the proxy. Obviously this is killing performance. In some cases, even using the handy and undocumented "Id" for Hibernate is still causing issues.
-Aaron