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:
and domain class implementation:
I also had to move domain class from grails-app/domain to src/groovy directory, otherwise application running failed with (grails-1.3.5):
Second problem with above implementation I have discovered is that when I turned on scaffolding (for testing purpose) by:
showing of created activity failed with error:
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.