2010-10-25 17 views
2

Je me demande s'il est possible d'implémenter le modèle de domaine suivant.Grails: mappage de classe de domaine (collection de types d'utilisateurs hibernate)

Ayons une classe de domaine qui contient un ensemble d'intervalles (temps joda). Je peux utiliser le type d'utilisateur hibernate org.joda.time.contrib.hibernate.PersistentInterval pour le mappage de Interval à la table de base de données (de la même manière que dans http://www.grails.org/JodaTime+Plugin). Cependant, je ne peux pas comprendre comment implémenter le mapping si j'ai un ensemble d'intervalles, pas seulement un intervalle.

Exemple:

class Activity { 
    ...  
    Set intervals = [] 
    ... 
    static hasMany = [  
     intervals: org.joda.time.Interval 
    ] 

    // This is incorrect implementation, I have set of intervals 
    // and this would be correct if I had only one interval 
    // How to implement mapping in this case? 
    static mapping = { 
     intervals type: PersistentInterval, { 
      column name: "start" 
      column name: "end" 
     } 
    } 

}

mise en œuvre ci-dessus échoue avec l'erreur suivante:

2010-10-23 18:30:25,483 [main] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) must have same number of columns as the referenced primary key (activity [id]) org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) must have same number of columns as the referenced primary key (activity [id]) at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

Je pensais que le travail autour de cette question est d'extraire l'intervalle de classe de domaine distinct extension d'intervalle et spécifier la cartographie dans les il. Cependant, Interval est la classe finale, donc l'extension n'est pas possible.

Merci pour vos conseils.

Répondre

3

Je réponds à ma propre question, peut-être que cette réponse sera utile pour quelqu'un.

Jusqu'à présent j'ai trouvé qu'une seule façon comment mettre en œuvre le modèle donné - par Hibernate XML mapping files:

<hibernate-mapping package="mappingtest"> 
    <class name="Activity"> 
     <id name="id"> 
      <generator class="native"/> 
     </id> 
     <set name="intervals"> 
      <key column="activity_id" not-null="true"/> 
      <element type="org.joda.time.contrib.hibernate.PersistentInterval"> 
       <column name="startDate"/> 
       <column name="endDate"/> 
      </element> 
     </set> 
    </class> 
</hibernate-mapping> 

et implémentation de la classe de domaine:

class Activity {  
    Long id  
    Set intervals = [] 

    static constraints = { 
    } 
} 

Je devais aussi déplacer la classe de domaine de grails- app/domain dans le répertoire src/groovy, sinon l'exécution de l'application a échoué avec (grails-1.3.5):

...
org.hibernate.DuplicateMappingException: Duplicate class/entity mapping mappingtest.Activity
...

Deuxième problème avec la mise en œuvre ci-dessus, je l'ai découvert est que lorsque je me suis tourné sur un échafaudage (à des fins de test) par:

class ActivityController { 
    static scaffold = true 
    ... 
} 

montrant l'activité créée échoué avec l'erreur:

Exception Message: No such property: id for class: org.joda.time.Interval Possible solutions: end Caused by: Error evaluating expression [i.id] on line [38]: No such property: id for class: org.joda.time.Interval Possible solutions: end

mais la mise en œuvre manuelle obtenir des activités de DB et son affichage a fonctionné. Edit: en plus j'ai trouvé la solution des problèmes d'échafaudage et DuplicateMappingException. Ils ont été causés par une localisation invalide de Activity.hbm.xml - la structure du répertoire du paquet était manquante. L'emplacement correct est grails-app/conf/hibernate/mappingtest/Activity.hbm.xml.