Grails: сопоставление классов домена (коллекция пользовательских типов в спящем режиме) - PullRequest
2 голосов
/ 25 октября 2010

Мне интересно, возможно ли реализовать следующую модель домена.

Давайте создадим класс домена, который содержит множество интервалов (время joda). Я могу использовать org.joda.time.contrib.hibernate. интервалы, а не только один интервал.

Пример:

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 [main] ОШИБКА context.GrailsContextLoader - Ошибка выполнение начальной загрузки: ошибка создания бин с именем 'messageSource': Не удалось инициализировать бин; вложенными исключение org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'actionManager ': не удается разрешить ссылка на bean-компонент 'sessionFactory' при настройке свойства бина 'SessionFactory'; вложенное исключение org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'sessionFactory': вызов init метод не удался; вложенное исключение org.hibernate.MappingException: Иностранный ключ (FK4FDC5B1E5107CA0: activity_intervals [начало, конец])) должно иметь одинаковое количество столбцы в качестве ссылочного первичного ключа (активность [id]) org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'messageSource': инициализация боб не удался; вложенное исключение org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'actionManager ': не удается разрешить ссылка на bean-компонент 'sessionFactory' при настройке свойства бина 'SessionFactory'; вложенное исключение org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем 'sessionFactory': вызов init метод не удался; вложенное исключение org.hibernate.MappingException: Иностранный ключ (FK4FDC5B1E5107CA0: activity_intervals [начало, конец])) должно иметь одинаковое количество столбцы в качестве ссылочного первичного ключа (активность [id]) в org.grails.tomcat.TomcatServer.start (TomcatServer.groovy: 212)

Я подумал, что для решения этой проблемы нужно извлечь Interval для разделения класса домена, расширяющего Interval, и указать в нем отображение. Тем не менее, Interval является конечным классом, поэтому его расширение невозможно.

Спасибо за ваши советы.

1 Ответ

3 голосов
/ 26 октября 2010

Я отвечаю на свой вопрос, может быть, этот ответ кому-нибудь пригодится.

До сих пор я нашел только один способ реализации данной модели - с помощью файлов отображения XML Hibernate :

<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: дублирование сопоставления класса / сущности, сопоставление.Activity
...

Вторая проблема с вышеописанной реализацией, которую я обнаружил, заключается в том, что при включении скаффолдинга (для целей тестирования):

class ActivityController {
    static scaffold = true
    ...
}

показ созданного действия завершился ошибкой:

Сообщение об исключении: Нет такого свойства: id для класса: org.joda.time.Interval Возможные решения: end Причина: ошибка при вычислении выражения [i.id] в строке [38]: Нет такого свойства: id для класса: org.joda.time.Interval Возможное решениеion: end

, но ручная реализация получения действий из БД и ее отображения работала.

Редактировать: дополнительно я нашел решение проблем с scaffolding и DuplicateMappingException.Они были вызваны неправильным расположением Activity.hbm.xml - структура каталога пакета отсутствовала.Правильное расположение: grails-app / conf / hibernate / mappingtest / Activity.hbm.xml.

...