开发者

Using JPA domain classes in Grails

开发者 https://www.devze.com 2023-03-12 22:05 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消