-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Hibernate reflection bugs with generics
PostPosted: Mon Oct 28, 2013 6:37 pm 
Newbie

Joined: Thu Jul 05, 2007 5:30 pm
Posts: 8
I wondered why my Unit-Test-Case fails:
http://m-m-m.sourceforge.net/surefire-report.html#net.sf.mmm.persistence.impl.hibernateEnversTest

So I debugged what is going on. Actually hibernate is creating a JdbcPreparedStatement with 3 parameters but fills in 4 parameters.
This is happening because Hibernated created a ComponentType for my ID of the type Long and the ComponentType is composed out of two Long values.
This again happens because of a bug that exists since Java 1.5.
I reported this bug with ID "1059797" to the Java Bugtracker with Summary "Duplicate Method in Class.getDeclaredMethods() if return type overridden" but as Java is anything but Open-Source issues are hidden until Sun or now Oracle thinks that the public should be able to see them, what never happened for my bug, even though it has been confirmed by tons of other users.
I spend ~1 year to implement reflection on POJOs that actually works without bugs and is able to determine the proper type of a property, etc.
http://m-m-m.sourceforge.net/mmm-util/mmm-util-core/apidocs/net/sf/mmm/util/pojo/descriptor/api/package-summary.html#documentation

You should be aware that both hibernate and springframework as very prominent OSS projects so far fail to do this correctly. The only other implementation I was not yet able to find bugs is in guava.

So what is going wrong:
If you define a generic method like
public abstract class AbstractEntity<ID> {
...
@Id
public ID getId()
...
}

and then sub-class like

public class MyEntity extends AbstractEntity<Long> {
@Id
@GeneratedValue
public Long getId() {
return super.getId();
}
}

then Java will return two Method instances for getId on MyEntity from getDeclaredMethod() what IMHO violates the contract of getDeclaredMethod() and is an obvious bug in Java but the makes do not care.
Therefore Hibernate recognizes two id properties and therefore sets two Long values in the JdbcPreparedStatement with the ID value exceeding the parameter index.

So my suggestion to the world is: never ever try to create jet another (buggy) implementation of property introspection or resolving of type variables. Instead use an existing solution that is proved to work correctly.
However, I you want to keep your own implementation here is my workaround/hack that you may want to consider:
https://github.com/m-m-m/mmm/blob/master/mmm-util/mmm-util-core/src/main/java/net/sf/mmm/util/pojo/descriptor/impl/PojoDescriptorBuilderImpl.java#L198

With kind regards
Jörg


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.