2010-10-25 69 views
2

我想知道是否有可能实现以下域模型。Grails:域类映射(休眠用户类型集合)

让我们有一个包含一组间隔(joda时间)的域类。我可以使用org.joda.time.contrib.hibernate.PersistentInterval休眠用户类型来将Interval映射到数据库表(通过与http://www.grails.org/JodaTime+Plugin类似的方式)。但是我不知道如何实现映射,如果我有一组间隔,而不是一个间隔。

实施例:

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" 
     } 
    } 

}

实现上述失败,以下错误:

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)

我认为工作解决此问题的是提取区间到单独的域类延伸区间与内指定映射它。但是,Interval是最后一堂课,所以不可能延续。

感谢您的建议。

回答

3

我在回答我自己的问题,也许这个答案对别人有用。

到现在为止,我发现只有一个办法如何实现给定的模型 - 通过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> 

和域类实现:

class Activity {  
    Long id  
    Set intervals = [] 

    static constraints = { 
    } 
} 

我也不得不从grails-移动领域类应用程序/域到src/groovy目录,否则应用程序运行失败(grails-1.3.5):

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

与上述实施我发现第二个问题是,当我打开支架(用于测试目的)由:

class ActivityController { 
    static scaffold = true 
    ... 
} 

显示创建活动的失败,出现错误:

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

但手工执行的从DB获取活动并显示其工作。

编辑:另外我找到了脚手架和DuplicateMappingException问题的解决方案。它们是由Activity.hbm.xml的无效位置导致的 - 程序包目录结构丢失。正确的位置是grails-app/conf/hibernate/mappingtest/Activity.hbm.xml。