Menu

ClassCastException for Sorted Sets

Help
Jam Flava
2006-03-15
2013-04-25
  • Jam Flava

    Jam Flava - 2006-03-15

    Hi,

    Using the beanlib to duplication a hibernate persistant class which has sorted collections causes class cast exceotions:

    java.lang.ClassCastException: com.saqib.MyClass
        at java.util.TreeMap.compare(TreeMap.java:1085)
        at java.util.TreeMap.put(TreeMap.java:463)
        at java.util.TreeSet.add(TreeSet.java:209)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicateCollection(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicate(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.transform(Unknown Source)
        at net.sf.beanlib.BeanPopulator.doit(Unknown Source)
        at net.sf.beanlib.BeanPopulator.processSetterMethod(Unknown Source)
        at net.sf.beanlib.BeanPopulator.populate(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.populate(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicate(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanTransformer.transform(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanReplicator.copy(Unknown Source)
        at net.sf.beanlib.hibernate.HibernateBeanReplicator.copy(Unknown Source)

    The class has a collection hibernate mapping that looks like this:
    ...
    <set name="..." table="..." cascade="all-delete-orphan" lazy="true" sort="com.saqib.MySorter">
    ...

    [I am Using Hibernate 2.x]

    Anyways, digging into your code, in the
    net.sf.beanlib.hibernate.HibernateBeanTransformer
    class, it seems that when you create a Collection for a SortedSet, you dont specify a Comparator, which will then lead to a ClassCastExceptions when adding something to this Collection. This happens in the following method:

    net.sf.beanlib.hibernate.HibernateBeanTransformer.createToCollection()

    So i modified this class to look like this:

        private Collection<Object> createToCollection(Collection<?> from)
            throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException
        {
            Class fromClass = from.getClass();
           
            if (isJavaPackage(fromClass))
                return createToInstanceAsCollection(from);
            if (from instanceof SortedSet) {
                        SortedSet asSortedSet = (SortedSet)from;
                        // add the comparator to the sorted set
                return new TreeSet<Object>(asSortedSet.comparator());
                    }
            if (from instanceof Set)
                return new HashSet<Object>();
            if (from instanceof List)
                return new ArrayList<Object>(from.size());
            // don't know what collection, so use list
            log.warn("Don't know what collection object:" + fromClass + ", so assume List.");
            return new ArrayList<Object>(from.size());
        }

    And it worked!

    I would say this is only a hack, since i am not an expert :)

    I would like to get your opinion of this.

    Also many thanks for this library! It saved me doing heaps of work to replicate Hibernate Persistent objects. Great Work!

    Regards,

    Saqib

     
    • Jam Flava

      Jam Flava - 2006-03-15

      Whoops... sorry, the code should be:

          private Collection<Object> createToCollection(Collection<?> from)
              throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException
          {
              Class fromClass = from.getClass();
             
              if (isJavaPackage(fromClass))
                  return createToInstanceAsCollection(from);
              if (from instanceof SortedSet) {
                          SortedSet asSortedSet = (SortedSet)from;
                          // add SortedSet's Comparator to the new TreeSet
                  return new TreeSet<Object>(asSortedSet.comparator());
                      }
              if (from instanceof Set)
                  return new HashSet<Object>();
              if (from instanceof List)
                  return new ArrayList<Object>(from.size());
              // don't know what collection, so use list
              log.warn("Don't know what collection object:" + fromClass + ", so assume List.");
              return new ArrayList<Object>(from.size());
          }

      Sorry for the confustion...

      Regards,

      Saqib

       
    • Joe D. Velopar

      Joe D. Velopar - 2006-03-15

      Hi Jam,

      Thanks for reporting this bug.  I think your proposed hack is a great hack :)  I wonder if we should also clone the comparator object across instead of just copying the reference...

      Would you be interested in writing a Junit Test case for this particular bug ?

      Hanson

       
    • Jam Flava

      Jam Flava - 2006-03-16

      Hi Hanson,

      hmm... cloning the Comparator... good question... cloning would make sence if the Comparator had properties that needed to be copied... but simply using the reference makes sence if the Comparator has no properties. Perhaps we could use the Hibernate Replicators to create a copy of it... or could there be another class that does this 'cloning' for you? I guess to cover all the bases, cloning would be the only option.

      I will write a JUnit Test case for this bug. I should have it tomorrow.

      Regards,

      Saqib

       
    • Joe D. Velopar

      Joe D. Velopar - 2006-03-23

      Hi Saqib,

      It turns out the fix is a little bit more complicated in the general case, and needs to be made both for SortedSet and SortedMap .

      Anyhow, it is now available for download in the beanlib-3.0.6 release.  Please let me know if any problem.

      Cheers,
      Hanson

       
    • Jam Flava

      Jam Flava - 2006-03-27

      Hi Hanson,

      My apologies for not getting back to you with that unit test... i started writing it... but then something came up at work. If you are still interested, i will finish it off.

      I will do a fresh checkout and try it out tomorrow.

      In the maintime, i found another "bug". I will post it in a new thread...

      Thanks for implementing the fix.

      Regards,

      Saqib

       
      • Joe D. Velopar

        Joe D. Velopar - 2006-03-28

        You may have a look at HibernateBeanReplicatorTestComparator.java which is a junit test for the comparator related changes.

        I am definitely interested if your tests cover more cases.

         

Log in to post a comment.