我想知道是否可以实现以下域模型。
让我们有一个包含一组间隔(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是最终类,因此无法进行扩展。
感谢您的建议。
答案 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。