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

让我们有一个包含一组间隔(joda 时间)的域类。我可以使用 org.joda.time.contrib.hibernate.PersistentInterval hibernate 用户类型将间隔映射到数据库表(通过与中类似的方式 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-错误执行引导程序:错误创建使用名称“ Messageource”的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]))必须具有与引用的主键(活动[id])org.springframework.beans.beans.factory.factory.beancreationexception:beanCreationexception:beancreationexception:错误创建使用名称“ Messageource”的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])) must have same number of columns as the referenced primary key (activity [id]) at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

我认为解决此问题的方法是将 Interval 提取到单独的扩展 Interval 的域类并指定其中的映射。然而,Interval 是最终类,因此不可能扩展。

感谢您的建议。

有帮助吗?

解决方案

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

到目前为止,我只找到了一种实现给定模型的方法 - 通过 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:重复的类/实体映射映射test.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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top