圣杯:域类映射(hibernate 用户类型的集合)
-
26-09-2019 - |
题
我想知道是否可以实现以下域模型。
让我们有一个包含一组间隔(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。