Grails:域类映射(hibernate用户类型的集合)

时间:2010-10-25 08:19:06

标签: hibernate grails mapping usertype grails-domain-class

我想知道是否可以实现以下域模型。

让我们有一个包含一组间隔(joda时间)的域类。我可以使用org.joda.time.contrib.hibernate.PersistentInterval hibernate用户类型将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 [主要]错误   context.GrailsContextLoader - 错误   执行bootstraps:创建错误   名为'messageSource'的bean:   bean的初始化失败;嵌套   例外是   org.springframework.beans.factory.BeanCreationException:   使用名称创建bean时出错   'transactionManager':无法解决   bean'sessionFactory'的引用   设置bean属性时   '的sessionFactory';嵌套异常是   org.springframework.beans.factory.BeanCreationException:   使用名称创建bean时出错   'sessionFactory':调用init   方法失败;嵌套异常是   org.hibernate.MappingException:   外键   (FK4FDC5B1E5107CA0:activity_intervals   [开始,结束]))必须具有相同的数量   列作为引用的主键   (活动[id])   org.springframework.beans.factory.BeanCreationException:   使用名称创建bean时出错   'messageSource':初始化   豆子失败了;嵌套异常是   org.springframework.beans.factory.BeanCreationException:   使用名称创建bean时出错   'transactionManager':无法解决   bean'sessionFactory'的引用   设置bean属性时   '的sessionFactory';嵌套异常是   org.springframework.beans.factory.BeanCreationException:   使用名称创建bean时出错   'sessionFactory':调用init   方法失败;嵌套异常是   org.hibernate.MappingException:   外键   (FK4FDC5B1E5107CA0:activity_intervals   [开始,结束]))必须具有相同的数量   列作为引用的主键   (活动[id])           在org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

我认为解决这个问题的方法是提取Interval以分离扩展Interval的域类并指定其中的映射。但是,Interval是最终类,因此无法进行扩展。

感谢您的建议。

1 个答案:

答案 0 :(得分: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-app / domain移动到src / groovy目录,否则应用程序运行失败(grails-1.3.5):

  

...
  org.hibernate.DuplicateMappingException:   重复的类/实体映射   mappingtest.Activity
  ...

我发现的上述实现的第二个问题是当我打开脚手架(用于测试目的)时:

class ActivityController {
    static scaffold = true
    ...
}

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

  

异常消息:没有这样的属性:   类的id:org.joda.time.Interval   可能的解决方案:结束由:   评估表达式[i.id]时出错   line [38]:没有这样的属性:id for   class:org.joda.time.Interval可能   解决方案:结束

但手动实现从DB获取活动及其显示效果。

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