jMar"s Blog DevSmash Developer Portal

Wednesday, February 6, 2008

Java, Reflection, Hibernate Proxy Objects, and Confetti

After spending the last 3 days scratching my head and pushing Google to its theoretical limits, I have just experienced the ever-satisfying thrill of success. It was one of those moments where a little hole appears in the clouds and a beam of light illuminates my desk while gold and silver confetti float down from the overhead sprinklers. It really was that good; I nearly made an announcement over the intercom.

So here's the setup: we have a web application running on a Weblogic Portal server and we're using Hibernate and Spring. Due to application growth and an expanding data model, we decided it was time to turn lazy loading on (with respect to Hibernate). Meanwhile I'm working on some form processing logic that (for the sake of this discussion) needed to be a runtime annotation consumer.

The section of code was to determine whether a form had values for all of the "Recommended Fields". The recommended fields were designated via a RecommendedField annotation in the model class. All this method knows is that the particular model object will extend MySuperClass. So it's pretty straight forward. Here's a basic outline of what I had going:

public static boolean isComplete(MySuperClass object) {

 Method[] methods = object.getClass().getMethods();
 for(Method method : methods) {
  RecommendedField rField = method.getAnnotation(RecommendedField.class);
  if( null != rField) {
   // do some logic, then return true or false 
  }
 }
 
 return true;
}

Nothing seems glaringly wrong in the code above, but to my consternation, method.getAnnotation() always returned null. Around this time I came to understand one of the side effects of Hibernate lazy loading. In order to allow lazy access to any relational objects, Hibernate returns a "proxy" object that essentially wraps and mimics the object that you wanted. This way when you call a getter, instead of throwing a NullPointerException, Hibernate can retrieve the result from the database.

Great... so what now? While the proxy object will suffice whenever you need to access a public property or method, it quickly becomes apparent that introspection and reflection present a problem. Since the proxy object is not truly an instance of the class that it is wrapping, metadata (such as annotations) are not there.

In truth, this realization was the key to solving the problem. Understanding that the annotations simply didn't exist on the object that I was inspecting prompted me to explore how to retrieve the non-proxy version of the object. Here is the solution that I ultimately came up with:

public static boolean isComplete(MySuperClass object) {
 /*
  *  The type casting below is necessary in order to read the annotations on the object's methods.
  *  The "MySuperClass" object that is passed into this method is really a Hibernate proxy object 
  *  that wraps the MySuperClass object (due to Hibernate's lazy loading).
  */
 if (object instanceof HibernateProxy) {
  object = (MySuperClass)((HibernateProxy)object).getHibernateLazyInitializer().getImplementation();
 }
  
 Method[] methods = object.getClass().getMethods();
 for(Method method : methods) {
  RecommendedField rField = method.getAnnotation(RecommendedField.class);
  if( null != rField) {
   // do some logic, then return true or false 
  }
 }
 
 return true;
}

*Cue confetti*

You'll notice that the commented addition is rather peculiar. It essentially takes the proxy object that was passed in and casts it as a HibernateProxy object. Calling getImplementation() returns a generic object, which I can then recast as a MySuperClass object (which is what it claimed to be in the first place). Since the object I am working with is now a real and true instance of MySuperClass, I can inspect the methods and their annotations without any problems.

There is a word of warning to throw in about this solution: since I am replacing the proxy object with the real object, my assumption is that it is now detached from the Hibernate session. Attempts at lazy loading on the object would most likely return null or throw a LazyLoadException (I have not tested to verify). In my case I don't need to access any more data, so it's not a problem. If your circumstances are different, you can simply create a new instantiation out of the casted object, or attempt to reattach the object to the Hibernate session when you're done.



41 comments:

Anonymous said...

hi. i read that in Hibernate, sometimes you have to fight the framework (i.e. it is one of its shortcomings). we are using jdbc currently and seems to work for us.

Anonymous said...

Thanks for the tip. It works great!!!

Eric said...

Thanks for the informative content. Saved me a lot of time, as I was attempting to architect a solution to convert Hibernate proxies to JAX-WS/JAXB objects via CXF. Works like a champ!

Jeremy Martin said...

@Eric
I have to admit, I wouldn't have thought of that particular solution, but I'm glad this was able to save you some time. I don't look back with too much fondness over that particular issue!

Anonymous said...

nice work!
I was looking for the part to identify hibernate proxies.

Anonymous said...

Thanks so much for the tip. I am working on a client/server disconnected model and this was what I was looking for. Saved me hours.

Anonymous said...

regarding to that article
for all the beginners in Hibernate ,

here you can find a nice video with step by step tutorial how to set up the environment In Hibernate

http://hibernatetutorial.com/Hibernate-tutorial-how-to-set-up-basic-Hibernate-development-environment.html

Alexander en Ilona said...

y tnx im using it too

Ali B said...

Thanks buddy :-) you're a legend!

Anonymous said...

Thank you so much!!! This is exactly what I was looking for!

Luiz said...

Thanks dude! This fits like a glove! Greetings from Brazil.

Anonymous said...

can i get the real object from proxy object without using hibernateproxy class?

Anonymous said...

Great help, thanks to you I can now evict a (now fully initialised) proxy object before entering into a nested conversation within seam, meaning no double nested parent flushing! Woo!

Anonymous said...

Thanks a lot, you saved me from having to pull out the rest of my hair!

WWE MOMENTS said...

happy mothers day

Grass-Fed-Whey said...

Well I am regular member of your blog feel so great to come here it gives me so much information about new topics whenever I come over your blog always get new information keep writing and updates us.
highest quality protein powder

quickloans said...

Hay, I am so happy to post on this blog, because it's was a very interesting and knowledgeable blogs post site. You are doing well; keep it up, best of luck
text loans direct lenders

1 yonge Condos said...

Its an informative and delightful blog I like to read this kind of posts. You have mentioned totally motivational and valuable content.
quick loans uk

virgin Hair Fixx said...

Awesome article, actually I was looking a website like this, I found all information here. You’re all article are gorgeous, I am very impressed. Thanks for sharing with us and keep posting.
short term loans easy repayment

1 yonge Condos said...

I must say It is a fantastic blog and this blog has one of the best platforms which is providing updated information. I feel necessary to give review on this blog. It's a really inspiring blog with full of knowledge. Book your Apartment in 1 Yonge Street

1 yonge Condos said...

I must say this is the fantastic blog your spread it in a very easy way it looks so comfortable to understand its good for me i visit here i like your way to give the information in a very easy manner it is really appreciate-able. 1 Yonge

Grass-Fed-Whey said...

Individual who made this post, this was an extremely nice post. Acknowledges for posting this, I saw a unite else alike notify however yours was the prime so deep, i really like your post.
best grass protein supplements

Mcity condos said...

Hello I feel so fortune to come over your blog to be a member of your blog it’s quit wonderful for me I always get so many new thing over your blog which helps me a lot keep writing and thanks for your bulk of knowledge.
Development in M city

Mcity condos said...

Hello I feel so fortune to come over your blog to be a member of your blog it’s quit wonderful for me I always get so many new thing over your blog which helps me a lot keep writing and thanks for your bulk of knowledge.
M City Condos Mississauga

Unknown said...

terima kasih semoga bermanfaat untuk kita semua. amiiin
.
.
.
.
.

zyraa fashion said...

Thanks for sharing the great informative article with excellent idea I really enjoyed your article Thanks for sharing this and keep writing. latest lehenga choli designs

ANNA Parker said...

Well this is an great post I really enjoyed it seems like bulk of knowledge you analogize and your writing skill so high for a newbie it is an amazing post s keep writing about new topics.
Dentist appleton

1 yonge Condos said...

I must say It's a informative blog and this blog has one of the best platforms which is providing great information. I feel necessary to give review on this blog. It's a really inspiring blog with full of knowledge. Luxurious Apartment In 1 Yonge Street

1 yonge Condos said...

Hey i agree with your views i must say it's a informative blog and this blog is providing great information. I feel necessary to give review on this blog. It's a really inspiring blog. Register Condos on 1 Yonge Street

Charisma Condos said...

This blog has useful information I must say you have ability to writing unique and informative content. Thanks for sharing this kind of valuable content. Available Condos for sale on Rutherford road

Charisma Condos said...

I am happy to find this post it's Very informative for me. This post is providing great information and well written blog. I totally agree with your points Thanks for sharing this kind of blog. real estate agent Rutherford road Vaughan

jacksonvilleseo said...

Well, this is my first visit to your blog! You have a genuine capacity for composing extraordinary Stuff. It is a fantastic blog its really inspiring and full fill with knowledge.keepit up
jacksonville seo firm

Grass-Fed-Whey said...

I am happy to find this post it's Very informative for me. This blog has useful information I must say you have ability to writing unique and informative content. It's a really inspiring blog with full of knowledge.
best grass protein supplements

1 yonge Condos said...

Very interesting article with great useful information. I am also sharing this article with my friends you have written excellent content. Thanks for sharing this kind of informative blog. luxurious Houses in Ontario

1 yonge Condos said...

I am so happy to read this blog and really It is helpful to me. I got lots of information from this blog thanks for write this kind of blog, keeps the spirit.
Real estate in Toronto

Charisma Condos said...

I want to to thank you for ones time due to this fantastic read! Always has really good posts and topics please keep it up.
http://www.charisma-condos.ca/greenpark-communities.php

monthloans said...

I always feel happy to read yours blogs, there is lots of information in your post, who is very useful to everyone, and your writing ability is so nice, keep it up
12 month loans same day payout

Mcity condos said...

Hey there I feel so fortunate to come over your blog you express it in a very easiest way I am very much active person over your blog pretty good to read your blog its quit interesting to read your blog always because it looks fresh all the time.
M City Condos

karmaayurveda12 said...

I am a regular visitor of your blog, I find always new updates on your post, really all information are very useful for everyone, today I want to share my experience in ayurvedic medicine. Ayurveda is the best way for kidney disease, without any dialysis. For more Knowledge
Ayurvedic Treatment of Kidney Disease

Ayurvedic Kidney Treatment In Delhi said...

Awesome blog post, I am a regular Visitor of your blog, whenever I come here I always get great information, Your blog template is so good, I love your all stuff, Thanks for making wonderful post.
Kidney Failure Treatment in ayurveda

MicheleDavila said...

Able to download and install the video clips and also can chrome actors. mobdro on kodi The individual can watch the high quality of video clips and there.