Использование классов домена JPA в Grails
Я хочу использовать модель домена JPA в приложении, разработанном с использованием новейшей вехи Grails (2.0.0.M1). Классы домена JPA находятся в каталоге src\java
приложения.
На основе этого сообщения в блоге, в котором описывается, как использовать существующую модель домена JPA в приложении Grails, я создал grails-app/conf/hibernate/hibernate.cfg.xml
со списком моих аннотированных классов JPA.
В случае, если кому-то достаточно скучно, чтобы захотеть запустить приложение, оно доступно здесь. При запуске приложения при запуске появляется следующая ошибка.
Error 2011-08-04 23:28:19,777 [Thread-8] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creati
ng bean with name 'grailsDomainClassMappingContext': Instantiation of bean failed; nested exception is org.springframewo
rk.beans.BeanInstantiationException: Could not instantiate bean class [org.codehaus.groovy.grails.domain.GrailsDomainCla
ssMappingContext]: Constructor threw exception; nested exception is java.lang.NullPointerException
Line | Method
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 138 | run in java.util.concurrent.FutureTask
| 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 662 | run . . in java.lang.Thread
Caused by BeanInstantiationException: Could not instantiate bean class [org.codehaus.groovy.grails.domain.GrailsDomainCl
assMappingContext]: Constructor threw exception; nested exception is java.lang.NullPointerException
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 138 | run in java.util.concurrent.FutureTask
| 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 662 | run . . in java.lang.Thread
Caused by NullPointerException: null
->> 123 | addPersistentEntityInternal in org.grails.datastore.mapping.model.AbstractMappingContext
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 115 | addPersistentEntity in ''
| 127 | addPersistentEntityInternal in ''
| 115 | addPersistentEntity in ''
| 127 | addPersistentEntityInternal in ''
| 115 | addPersistentEntity in ''
| 303 | innerRun in java.util.concurrent.FutureTask$Sync
| 138 | run in java.util.concurrent.FutureTask
| 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 662 | run . . in java.lang.Thread
Любопытно, что проблема только кажется вызванной классами домена, которые имеют отношения с другими классами домена. Если вы удалите все классы домена, кроме SystemProperty
(который не относится к другим классам домена), приложение запускается без ошибок.
Ответы
Ответ 1
Попробуйте использовать META-INF/persistence.xml
(пример) (я не знаю, где именно разместить его, но в конечном итоге он должен перейти в WEB-INF/META-INF/persistence.xml
и включите в него свой файл jar (в элементе <jar-file>
). Тогда вам, конечно, понадобится все spring beans (LocalEntityManagerFactoryBean
)
Ответ 2
Документация 1.3.7 сообщает
Просто поместите файлы сопоставления в grails-app/conf/hibernate и либо поместить файлы Java в src/java, либо (если модель домена хранятся в JAR) упакованные классы в проект lib каталог.
Я не видел вашу банку в каталоге lib
в вашем исходном коде. Может ли это так?
Ответ 3
Если вы посмотрите на сценарии запуска Grails ($ GRAILS_HOME $/bin/grails и $GRAILS_HOME $/bin/startGrails), вы можете узнать, какой аргумент classpath отправляется в приложение laulesher grails org.codehaus.groovy.grails.cli.support.GrailsStarter.
Когда вы выполняете команду grails generate-all com.model.User, grails ожидает, что она будет доступна в исходной папке или в каталоге lib. В вашем сценарии банка доступна как часть зависимости от Maven. Эта информация не передается по запуску grails script. Вы должны указать эту информацию.
У запуска script есть возможность указать путь к классам. Следовательно, вам нужно вызвать команду grails с опцией classpath, которая указывает местоположение банок.
grails generate-all -cp E:\workspace\AppDomain.jar
Вы также должны упомянуть банку с другими командами.
Пример: grails run-app -cp E:\workspace\AppDomain.jar
Вам понадобится механизм для получения всех зависимостей Maven как аргумента classpath.
Я тестировал примерный класс домена JPA, и это работает.