-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: map index-to-many generates invalid generic Map type
PostPosted: Wed Oct 12, 2005 9:48 am 
Newbie

Joined: Wed Oct 12, 2005 9:25 am
Posts: 2
Location: Maryland, USA
The code generated by hibernatetool generates an invalid Map Type for generics. There is a Value type parameter, but no Key type parameter.

Hibernate version: hibernate tools CVS version on 20051009

Mapping document:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--
        Auto-generated mapping file from
        the hibernate.org cfg2hbm engine
-->
    <class name="com.praxiseng.reservations.db.Person" table="PERSON" schema="GLMATRA_T2">
        <id name="personId" type="integer">
            <column name="PERSON_ID" precision="22" scale="0" />
            <generator class="native" />
        </id>
        <map name="seatByFlight"
           table="SEAT_ON_FLIGHT">
           <key column="PERSON_ID"/>
           <index-many-to-many
              class="com.praxiseng.reservations.db.Flight" />
           <many-to-many class="com.praxiseng.reservations.db.Seat"
              column="SEAT_ID"/>
        </map>
    </class>
</hibernate-mapping>


Generated code:
Code:
private Map<com.praxiseng.reservations.db.Seat> seatByFlight;

should be:
Code:
private Map<com.praxiseng.reservations.db.Flight, com.praxiseng.reservations.db.Seat> seatByFlight;



Ant target:
Code:
    <target name="hbm2java">
       <taskdef name="hibernatetool"
          classname="org.hibernate.tool.ant.HibernateToolTask"
          classpathref="hibernate.path" />
       <hibernatetool destdir="generated" >
          <configuration
             configurationfile="config/hibernate.cfg.xml">
             <fileset dir="generated">
                <include name="**/*.hbm.xml"/>
             </fileset>
          </configuration>
          <hbm2cfgxml destdir="generated"/>
          <hbm2java destdir="generated" generics="true" />
       </hibernatetool>
    </target>


Generated java property:
Code:
private Map<com.praxiseng.reservations.db.Seat, com.praxiseng.reservations.db.Flight> seatByReservation;


I think this is a bug. I went ahead and changed my local copy of Cfg2JavaTool.getRawTypeName() by adding support for Indexed Collections.
Here is my addition...
Code:
            if( value instanceof IndexedCollection) {
               IndexedCollection ic = (IndexedCollection) value;
               String genericParams;
               String entityType;
               ManyToOne element = (ManyToOne) ic.getElement();
               ManyToOne index = (ManyToOne) ic.getIndex();
               
               entityType = element.getReferencedEntityName();
               if(index != null) {
                  String indexType;
                  indexType = index.getReferencedEntityName();
                  genericParams = "<" + indexType  + ", " + entityType+ ">";
               } else {
                  genericParams = "<" + entityType + ">";
               }
               return getJavaTypeName(value, preferRawTypeNames) + genericParams;
            } else if ( value instanceof Collection ) {


Here is my full version of the method...
Code:
   private String getRawTypeName(Property p, boolean useGenerics, boolean preferRawTypeNames) {
      Value value = p.getValue();
      try {         
         if ( value instanceof Array ) { // array has a string rep.inside.
            Array a = (Array) value;            
               
            if ( a.isPrimitiveArray() ) {
               return toName( value.getType().getReturnedClass() );
            }
            else if (a.getElementClassName()!=null){
               return a.getElementClassName() + "[]";
            } else {
               return getJavaTypeName(a.getElement(), preferRawTypeNames) + "[]";
            }
         }

         if ( value instanceof Component ) { // same for component.
            return ( (Component) value ).getComponentClassName();
         }
         
         if ( useGenerics ) {
            if( value instanceof IndexedCollection) {
               IndexedCollection ic = (IndexedCollection) value;
               String genericParams;
               String entityType;
               ManyToOne element = (ManyToOne) ic.getElement();
               ManyToOne index = (ManyToOne) ic.getIndex();
               
               entityType = element.getReferencedEntityName();
               if(index != null) {
                  String indexType;
                  indexType = index.getReferencedEntityName();
                  genericParams = "<" + indexType  + ", " + entityType+ ">";
               } else {
                  genericParams = "<" + entityType + ">";
               }
               return getJavaTypeName(value, preferRawTypeNames) + genericParams;
            } else if ( value instanceof Collection ) {
               Collection collection = (Collection) value;
               String entityType;
               if ( collection.isOneToMany() ) {
                  OneToMany oneToMany = (OneToMany) collection.getElement();
                  entityType = oneToMany.getAssociatedClass().getClassName();
               }
               else {
                  ManyToOne manyToOne = (ManyToOne) collection.getElement();
                  entityType = manyToOne.getReferencedEntityName();
               }

               return getJavaTypeName(value, preferRawTypeNames) + "<" + entityType + ">";
            }
         }

         return getJavaTypeName( value, preferRawTypeNames );         
      }
      catch (Exception e) {
         //e.printStackTrace();
         String msg = "Could not resolve type without exception for " + p + " Value: " + value;
         if ( value != null && value.isSimpleValue() ) {
            String typename = ( (SimpleValue) value ).getTypeName();
            log.warn( msg + ". Falling back to typename: " + typename );
            return typename;
         }
         else {
            throw new ExporterException( msg, e );
         }
      }
   }



I don't know if this is the best way to fix it or not as this is the first time I've fished around in the hibernate-tools source.

Thanks,
Geoff

Disclamer: No code in this post came from an actual project from my employer, it was generated just for use as an example.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 1:35 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
submit a patch to our jira - thanks.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: Looks like Ryan Lynch beat me to it
PostPosted: Mon Oct 17, 2005 9:34 am 
Newbie

Joined: Wed Oct 12, 2005 9:25 am
Posts: 2
Location: Maryland, USA
HBX-224 looks like it also fixes this problem. However, his code only fixes instanceof org.hibernate.mapping.Map should it be made more general and cover instanceof IndexedCollection?

Thanks,
Geoff


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.