Uploaded image for project: 'JBoss Enterprise Application Platform 4 and 5'
  1. JBoss Enterprise Application Platform 4 and 5
  2. JBPAPP-3565

HHH-4851 OneToOneSecondPass Metadata is mistakenly interpreted

    XMLWordPrintable

    Details

    • Affects:
      Release Notes

      Description

      http://opensource.atlassian.com/projects/hibernate/browse/HHH-4851

      I've been tracking an issue that has been causing us some trouble
      regarding annotation-based hibernate mappings. The exception occurs at
      run-time only:
      /org.hibernate.PropertyValueException: not-null property references a
      null or transient value ...
      /
      At first I believed we had an issue with our entity mapping was faulty
      and went to try and figure it out... However, I came accross several
      examples on the wide internet and showed that my mapping seems
      correct. Furthermore, I had some other entities mapped in a similar
      fashion that did not cause any issue... How could that be?

      I traced the Hibernate code to a class named
      org.hibernate.cfg.OneToOneSecondPass (Hibernate Annotations 3.4.0.GA
      for those interested to look at the code) up to line 147:

      ...
      Iterator it = otherSide.getJoinIterator();
      Join otherSideJoin = null;
      while ( it.hasNext() ) {
      otherSideJoin = (Join) it.next();
      if ( otherSideJoin.containsProperty( otherSideProperty ) )

      { break; }

      }
      if ( otherSideJoin != null )

      { ... }
      ...

      If you look closely, it seems that if there are JOINs but none
      contains the otherSideProperty, the variable otherSideJoin will not be
      null and will contains the last joins of the iterator even if it is
      not valid.

      The patched-up code would look like:

      ...
      Iterator it = otherSide.getJoinIterator();
      Join otherSideJoin = null;
      while ( it.hasNext() ) {
      Join otherSideJoinValue = (Join) it.next();
      if ( otherSideJoinValue.containsProperty( otherSideProperty ) ) { otherSideJoin = otherSideJoinValue; break; }
      }
      if ( otherSideJoin != null ) { ... }

      }
      ...

      To fix my issue, I applied this patch:
      Index: src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
      ===================================================================
      — src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
      (revision 18572)
      +++ src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
      (working copy)
      @@ -146,8 +146,9 @@
      Iterator it = otherSide.getJoinIterator();
      Join otherSideJoin = null;
      while ( it.hasNext() ) {

      • otherSideJoin = (Join) it.next();
      • if ( otherSideJoin.containsProperty(
        otherSideProperty ) )
        Unknown macro: {+ Join otherSideJoinValue = (Join) it.next();+ if ( otherSideJoinValue.containsProperty(otherSideProperty ) ) { + otherSideJoin = otherSideJoinValue; break; }

        }

      I compiled the code locally and re-tried my failing code and it worked
      beautifully. it seemed that my last joins in the iterator has a
      nullable = false which caused the runtime
      /org.hibernate.PropertyValueException: not-null property references a
      null or transient value/

      If you take a look at the attached file unit-test.zip which contains a sample of code which reproduce the issue.

      The other file attached contains the fixed I applied to the source-code to eliminate the problem

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                stliu Strong Liu
                Reporter:
                stliu Strong Liu
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: