2

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

让我们有一个包含一组间隔(joda time)的域类。我可以使用 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 [main] ERROR context.GrailsContextLoader - 执行引导程序时出错:创建名为“messageSource”的 bean 时出错:bean 初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException:外键 (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与引用的主键 (activity [id]) org.springframework 具有相同的列数。beans.factory.BeanCreationException:创建名为“messageSource”的bean时出错:bean初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) BeanCreationException:创建名为“messageSource”的 bean 时出错:bean 初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) BeanCreationException:创建名为“messageSource”的 bean 时出错:bean 初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) 创建名为“messageSource”的 bean 时出错:bean 初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) 创建名为“messageSource”的 bean 时出错:bean 初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) bean初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) bean初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“transactionManager”的 bean 时出错:设置 bean 属性“sessionFactory”时无法解析对 bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) BeanCreationException:创建名为“transactionManager”的bean时出错:设置bean属性“sessionFactory”时无法解析对bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) BeanCreationException:创建名为“transactionManager”的bean时出错:设置bean属性“sessionFactory”时无法解析对bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) 嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212) 嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: Foreign key (FK4FDC5B1E5107CA0:activity_intervals [start,end])) 必须与 org.grails.tomcat.TomcatServer.start( TomcatServer.groovy:212)

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

感谢您的建议。

4

1 回答 1

3

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

到目前为止,我只找到了一种实现给定模型的方法——通过Hibernate XML 映射文件

<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 可能的解决方案:结束原因:在第 [38] 行评估表达式 [i.id] 时出错:没有这样的属性:类的 id:org.joda .time.Interval 可能的解决方案:结束

但是手动执行从数据库获取活动及其显示的工作。

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

于 2010-10-26T16:43:03.533 回答