I want to use a JPA domain model in an application developed using the latest Grails milestone (2.0.0.M1). The JPA domain classes are in the src\java
directory of the application.
Based on this blog post which describes how to use an existing JPA domain model in a Grails app, I created grails-app/conf/hibernate/hibernate.cfg.xml
with a list of my JPA-annotated classes.
In case anyone is bored enough to want to run the app themselves, it's available here. When you run the application the following error occurs on startup
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
Curiously, the problem only seems to be triggered by domain classes that have relationships with other domain classes. If you remove all domain classes except SystemProperty
(which doesn't refer to other domain classes), the app starts without error.
Try using META-INF/persistence.xml
(example) (I don't know where exactly to place it, but it should ultimately go to WEB-INF/META-INF/persistence.xml
, and include your jar file there (in <jar-file>
element). Then of course you will need all respective spring beans (LocalEntityManagerFactoryBean
for example)
The 1.3.7 documentation says
Simply place the mapping files into grails-app/conf/hibernate and either put the Java files in src/java or (if the domain model is stored in a JAR) the packaged classes into the project's lib directory.
I didn't see your jar in the lib
directory in your source code. Could this be it?
If you look into the grails startup scripts ( $GRAILS_HOME$/bin/grails and $GRAILS_HOME$/bin/startGrails), you can find out the classpath argument being sent to the grails application launcher org.codehaus.groovy.grails.cli.support.GrailsStarter.
When you execute the command grails generate-all com.model.User, the grails expects it to be available in the source folder or the lib directory. In your scenario, the jar is available as part of Maven dependency. This information is not passed along the grails startup script. You need to specify this information.
The startup script has the option to specify the classpath. Hence, you need to invoke the grails command with the classpath option that specifies the location of the jars.
grails generate-all -cp E:\workspace\AppDomain.jar
You need to mention the jar with other commands as well. Ex: grails run-app -cp E:\workspace\AppDomain.jar
You will need a mechanism to get all Maven dependencies as classpath argument.
I have tested with a sample JPA domain class and this works.
精彩评论