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

发布于 2024-09-29 02:15:03 字数 1904 浏览 7 评论 0原文

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

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

例子:

类活动{  
   ...    
   设置间隔 = []  
   ...  
   静态有很多 = [    
       间隔:org.joda.time.Interval  
   ]  

   // 这是不正确的实现,我有一组间隔  
   // 如果我只有一个时间间隔,这将是正确的  
   // 这种情况下如何实现映射呢?  
   静态映射= {  
       间隔类型:PersistentInterval,{  
           列名称:“开始”  
           栏目名称:“结束”  
       }  
   }  

}

失败并出现以下错误:

2010-10-23 18:30:25,483 [主要] 错误 context.GrailsContextLoader - 错误 执行引导程序:创建时出错 名为“messageSource”的 bean: bean 初始化失败;嵌套的 例外是 org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 “transactionManager”:无法解析 引用 bean 'sessionFactory' 设置bean属性时 '会话工厂';嵌套异常是 org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 'sessionFactory':调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: 外键 (FK4FDC5B1E5107CA0:活动间隔 [开始,结束])) 必须具有相同的数量 列作为引用的主键 (活动[id]) org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 “messageSource”:初始化 豆失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 “transactionManager”:无法解析 引用 bean 'sessionFactory' 设置bean属性时 '会话工厂';嵌套异常是 org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 'sessionFactory':调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: 外键 (FK4FDC5B1E5107CA0:活动间隔 [开始,结束])) 必须具有相同的数量 列作为引用的主键 (活动[id]) 在 org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

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

感谢您的建议。

I am wondering if is possible to implement following domain model.

Let's have a domain class which contains set of intervals (joda time). I can use org.joda.time.contrib.hibernate.PersistentInterval hibernate user type for mapping of Interval to database table (by similar way as in http://www.grails.org/JodaTime+Plugin). However I cannot figure out how to implement mapping if I have set of intervals, not only one interval.

Example:

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

}

Implementation above fails with following error:

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)

I thought that work-around of this issue is to extract Interval to separate domain class extending Interval and specify mapping within it. However, Interval is final class so extending is not possible.

Thanks for your advices.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不一样的天空 2024-10-06 02:15:03

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

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

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

class ActivityController {
    static scaffold = true
    ...
}

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

异常消息:没有这样的属性:
班级 ID:org.joda.time.Interval
可能的解决方案:结束 原因:
计算表达式 [i.id] 时出错
第 [38] 行:没有这样的属性:id for
类: org.joda.time.Interval 可能
解决方案:结束

但手动实施从数据库获取活动及其显示工作。

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

I am replying my own question, maybe this answer will be useful for someone.

Until now I have found only one way how to implement given model - by 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>  

and domain class implementation:

class Activity {    
    Long id    
    Set intervals = []

    static constraints = {
    }
}

I also had to move domain class from grails-app/domain to src/groovy directory, otherwise application running failed with (grails-1.3.5):

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

Second problem with above implementation I have discovered is that when I turned on scaffolding (for testing purpose) by:

class ActivityController {
    static scaffold = true
    ...
}

showing of created activity failed with error:

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

but manual implementation of getting activities from DB and its showing worked.

Edit: additionally I found solution of scaffolding and DuplicateMappingException issues. They were caused by invalid location of Activity.hbm.xml - package directory structure was missing. Correct location is grails-app/conf/hibernate/mappingtest/Activity.hbm.xml.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文