8 Replies Latest reply on Mar 13, 2007 2:34 PM by Jan Vervecken

    jdev    oracle.jbo.domain.Date problem  (BUG???)

      I have found problem regarding oracle.jbo.domain.Date class which I think should be treated as bug. Comparing java.util.Date object with object returned by getValue() method of oracle.jbo.domain.Date is not commute. Suppose we have one object java.util.Date A and second oracle.jbo.domain.Date B object. If both are set to the same date value than both A.equals(B.getValue()) and B.getValue().equals(A) should give true but it is not the case. Second expression gives false. The reason of this is that the equals() method in the second expression is not from java.util.Date but from java.sql.Timestamp. java.sql.Timestamp is class of result from oracle.jbo.domain.Date.getValue() if date has time different than 00:00:00. Code of method oracle.jbo.domain.Date.getValue() should not use casting to java.util.Date but should return new java.util.Date object to ensure commutable comparison. Even worse situation is if one tries to use comparTo() metod of java.util.Date because it gives class cast exception.
      Below small example to test the case

      oracle.jbo.domain.Date oraDate = new oracle.jbo.domain.Date();
      java.util.Date utilDate = new java.util.Date();
      long longDate = 1172737018000L;
      oraDate.setBytes( DATE.toBytes( new java.sql.Timestamp( longDate ) ) );

      System.out.printf("oradate %tF %tT %tQ\n" ,
      System.out.printf("utildate %tF %tT %tQ\n",

      System.out.println( oraDate.getValue().equals(utilDate) ); // false
      System.out.println( utilDate.equals(oraDate.getValue()) ); // true
        • 1. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
          this class oracle.jbo.domain.Date don´t have this constructor oracle.jbo.domain.Date ( java.util.Date date)

          you can change your java.util.Date for a java.sql.Date and you can do your parse more easy
          • 2. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
            My code above is only for testing problem not real life program. In real code one object is java.util.Date and second is taken from database row implementation (in database DATE and in ViewObject is oracle.jbo.domain.Date). To compare both I use equals() metod.Of course as I hope is clear from first message not directly but with result of getValue() method.
            • 3. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
              Jan Vervecken

              As much as this looks like a bug, it also looks like a "documented feature".
              see http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Timestamp.html

              "Note: This type is a composite of a java.util.Date and a separate nanoseconds value. Only integral seconds are stored in the java.util.Date component. The fractional seconds - the nanos - are separate. The Timestamp.equals(Object) method never returns true when passed a value of type java.util.Date because the nanos component of a date is unknown. As a result, the Timestamp.equals(Object) method is not symmetric with respect to the java.util.Date.equals(Object) method. Also, the hashcode method uses the underlying java.util.Date implementation and therefore does not include nanos in its computation."

              "Due to the differences between the Timestamp class and the java.util.Date class mentioned above, it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance."

              Jan Vervecken
              • 4. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
                Jan Vervecken

                But, also the java.util.Date equals() method is documented with:
                "Thus, two Date objects are equal if and only if the getTime method returns the same long value for both."
                see http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html#equals(java.lang.Object)

                And in your example, this ...
                System.out.println("oraDate.getValue().getTime() = " + oraDate.getValue().getTime());
                System.out.println("utilDate.getTime() = " + utilDate.getTime());
                results in this ...
                oraDate.getValue().getTime() = 1172737018000
                utilDate.getTime() = 1172737018000
                Interesting question, maybe someone with more "date experience" can answer this.

                Jan Vervecken
                • 5. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
                  thank Jan for your replies, and sorry for my delay - I was far from computers recently :-).
                  For me it is not problem with java.util.Date and java.sql.Timestamp but oracle.jbo.domain.Date. It results from how java.util.Date and java.sql.Timestamp relates and that in Timestamp class some methods are overridden. Instead of casting to java.util.Date in return of getValue() method of oracle.jbo.domain.Date class should be creating new java.utilDate object. This way always result from getValue() will always be java.util.Date.
                  And, more general, it is also very good example how careful one should be with casting. Thou casting in oracle.jbo.domain.Date.getValue() is valid, results in very error prone design.
                  • 6. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
                    Jan Vervecken
                    hi Remi

                    I understand your issue results from the oracle.jbo.domain.Date class implementation.

                    But, because "the inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance" a discussion about this becomes more confusing because the term "is a" no longer has its typical semantics.

                    • 7. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
                      Hi Jan,
                      yes you're of course right about merit of this problem. But I think that if it is possible to make something clear why not to do this way? If oracle.jbo.domain.Date.getValue() would return always java.util.Date (as it is the case when not using casting but new java.utilDate() ) error prone situation would no longer exist. And I suppose this change is safe for existing applications code.
                      • 8. Re: jdev    oracle.jbo.domain.Date problem  (BUG???)
                        Jan Vervecken
                        hi Remi

                        Indeed, this could benefit from some clarification.

                        If only someone from Oracle would point us to some documentation we missed or give some other kind of explanation.