Details

    • Type: Improvement
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects versions: 4.2.7
    • Fix versions: None
    • Components: hibernate-core
    • Labels:
      None
    • Environment:
      tested on windows with H2 but surely independent from this
    • Last commented by a user?:
      true
    • Sprint:

      Description

      No reaction in forum to my bug so I create a JIRA issue for it:
      https://forum.hibernate.org/viewtopic.php?f=1&t=1029259

      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, if 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

        Attachments

          Activity

            People

            • Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated: