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
|