Grails:域类映射(收集休眠用户类型) [英] Grails: domain class mapping (collection of hibernate user types)

查看:219
本文介绍了Grails:域类映射(收集休眠用户类型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



让我们有一个包含一组间隔(joda时间)的域类。我可以使用org.joda.time.contrib.hibernate.PersistentInterval hibernate用户类型来将Interval映射到数据库表(通过类似于 http://www.grails.org/JodaTime+Plugin )。然而,我不知道如何实现映射,如果我有一组间隔,而不是一个间隔。



示例:


  class Activity {
...
Set intervals = []
...
static hasMany = [
间隔:org.joda.time.Interval
]

//这是不正确的实现,我有一组间隔
//这会是正确的,如果我只有一个区间
//如何在这种情况下实现映射?
静态映射= {
间隔类型:PersistentInterval,{
列名:start
列名:end
}
}

}


上面的实现失败,出现以下错误:


2010-10-23 18:30:25,483 [main]错误
上下文。 GrailsContextLoader - 错误
执行bootstraps:创建名为'messageSource'的
bean时出错:
Bean初始化失败;嵌套的
异常是
org.springframework.beans.factory.BeanCreationException:
创建名为
的bean的错误'transactionManager':无法解析
引用bean'sessionFactory'
设置bean属性
'sessionFactory';嵌套异常是
org.springframework.beans.factory.BeanCreationException:
创建名为
'sessionFactory'的bean时出错:调用init
方法失败;嵌套异常是
org.hibernate.MappingException:
外键
(FK4FDC5B1E5107CA0:activity_intervals
[开始,结束]))必须具有与
列相同数量的引用的主键
(activity [id])
org.springframework.beans.factory.BeanCreationException:
创建名为
'messageSource'的bean的错误:初始化
豆失败;嵌套的异常是
org.springframework.beans.factory.BeanCreationException:
创建bean的名称为
'transactionManager'时出错:无法解析
引用bean'sessionFactory'
同时设置bean属性
'sessionFactory';嵌套异常是
org.springframework.beans.factory.BeanCreationException:
创建名为
'sessionFactory'的bean时出错:调用init
方法失败;嵌套异常是
org.hibernate.MappingException:
外键
(FK4FDC5B1E5107CA0:activity_intervals
[开始,结束]))必须具有与
列相同数量的引用的主键
(activity [id])
at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)

我认为解决此问题的方法是提取Interval以分隔扩展Interval的域类并指定其中的映射。但是,Interval是最后一堂课,所以不可能延续。



感谢您的建议。

解决方案

我回复我自己的问题,也许这个答案对别人有用。 b $ b

到现在为止,我只找到一种方法来实现给定的模型 - 通过 Hibernate XML映射文件

 < hibernate-mapping package =mappingtest> 
< class name =Activity>
< id name =id>
< generator class =native/>
< / id>
< set name =intervals>
< key column =activity_idnot-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 = {
}
}

我还必须将domain class从grails-app / domain移动到src / groovy目录,否则应用程序运行失败使用(grails-1.3.5):


...

org.hibernate.DuplicateMappingException:
复制类/实体映射
mappingtest.Activity

...


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

  class ActivityController {
static scaffold = true
...
}

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


异常消息:没有这样的属性:
id fo r类:org.joda.time.Interval
可能的解决方案:end引起:

行[38]上评估表达式[i.id]时出错:没有这样的属性:id为
class:org.joda.time.Interval可能的
解决方案:end


但手动实现从DB和它的显示工作。



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


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.

解决方案

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.

这篇关于Grails:域类映射(收集休眠用户类型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆