4
votes

I am migrating my grails project from using Hibernate XML to just GORM defined in the domain classes. In one prior XML file there is a map defined:

<?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 package="myproj" default-lazy="true">

    <class name="Season" table="seasons">
        <cache usage="read-only"/>
        <comment>Season</comment>
        <id name="id" type="long">
            <generator class="assigned">
            </generator>
        </id>

        <property name="seasonKey" column="season_key"/>
        <many-to-one name="league" class="Affiliation" column="league_id"/>
        <many-to-one name="publisher" class="Publisher"/>

        // MAP STARTS HERE
        <map name="seasonWeeks">
            <cache usage="read-write"/>          
            <key column="season_id"></key>
            <map-key column="week" type="int"/>
            <one-to-many class="SeasonWeek"/>
        </map>

    </class>

</hibernate-mapping>

As you can see, it creates a map of Integer, SeasonWeek. This code was previously working.

When I try to recreate the Map in GORM, it doesn't work. The Grails 1.3.7 (the version I am on) documentation states:

The static hasMany property defines the type of the elements within the Map. The keys for the map must be strings.

In my case I don't want the map to be a string. Questions:

  • Is there any way I can do what I want here? Maybe through using the static mapping var?
  • If not, must I reinstate the old Hibernate XML file? Can I do this for just one domain class in my project and not have XML files for the rest?

Thanks.

1

1 Answers

4
votes

I've found that trying to get some things to work in grails from legacy apps using GORM just isn't the easiest thing to do. You can find a solution that fits 99% of your problems but you'll spend a bunch more time trying to find an easy button for the last 1% of issues (like yours). I think you could accomplish this by using a transient field as the key some like (note there are two solutions, i recommend the second)...

class Season {

    static mapping = {
        seasonWeeks mapKey: 'weekOfYearAsString' 
    }

    static hasMany = [seasonWeeks:SeasonWeek]

    Map seasonWeeks = [:]
}


 class SeasonWeek{

        ...

        String name
        Integer weekOfYearAsInt
        String weekOfYearAsString

        String getWeekOfYearAsString(){
            return String.valueOf(weekOfYearAsInt);
        }

        void setWeekOfYearAsString(def value){
            this.weekOfYearAsInt = Integer.parseInt(value);
        }
    }

ALSO You could avoid GORM completely (what i would do) and just handle building a map on your Season class...

class Season{

   ...

    public Map getSeasonWeeksMap(){
        Map map = [:]
        def seasons = SeasonWeek.findBySeason(this.id)

        season.each(){season ->
            map.put(season.id, season)

        }

        return map
    }
}