Hi all,
OpenJPA 1.2.2 is not generating my schema at compile time in a
Spring-based MVC webapp, and I can't figure out why. See below for
details. Help is appreciated.
I am compiling, enhancing and jarring my entities in a jar called
case-model-1.1.0-SNAPSHOT.jar, that does NOT contain a
META-INF/persistence.xml or a META-INF/orm.xml, because they need to
be determined at run time. Additionally, some of the entities have
annotation-based mapping information defaults, like @Column which I'd
like to have honored unless overridden by xml-based mapping metadata.
Higher up in the dependency chain and in a separate project, I have a
Spring web app that uses a service that depends on my entities, where
I need to configure a custom persistence.xml and orm.xml that needs to
be used along with the entities and their (possibly overridden)
annotation-based mappings in the web app environment.
I have put my Spring configuration files in WEB-INF/spring for all of
the application, and the Spring configuration is configured with the
help of a properties file located in a directory, call it
"/configuration", that is made available to the web application but is
not part of the web application itself. The diretory /configuration
contains a directory called "linx2", wherein are located all of my
configuration files. A properties file, called
"linx2/linx2.properties", allows a user to indicate the database type
in use via the "linx2.db.type" property, for example:
linx2.db.type=hsqldb-memory
linx2.db.url=jdbc:hsqldb:mem:linx2
linx2.db.driver=org.hsqldb.jdbcDriver
linx2.db.user=sa
linx2.db.password=
...
That property is used in my Spring config to determine which
persistence.xml and openjpa properties file to use:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="case-model" />
<property name="persistenceXmlLocation"
value="classpath:/linx2/${linx2.db.type}-case-model-persistence.xml" />
<property name="jpaProperties">
<util:properties
location="classpath:/linx2/${linx2.db.type}-openjpa.properties" />
</property>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
For good measure, here's my dataSource bean:
<bean class="org.apache.commons.dbcp.BasicDataSource" name="dataSource">
<property name="driverClassName" value="${linx2.db.driver}" />
<property name="url" value="${linx2.db.url}" />
<property name="username" value="${linx2.db.user}" />
<property name="password" value="${linx2.db.password}" />
</bean>
Because linx2.db.type is "hsqldb-memory", the persistence.xml file
should be "linx2/hsqldb-memory-case-model-persistence.xml" and the
openjpa properties file used should be
"linx2/hsqldb-memory-openjpa.properties", both located in the
directory "/configuration", which is on the classpath available to the
webapp. Note that hsqldb-memory-case-model-persistence.xml is not in
/configuration/linx2/META-INF -- it's directly in
/configuration/linx2/.
The contents of linx2/hsqldb-memory-openjpa.properties follow. Note
the use of classpath scanning for the jar,
case-model-1.1.0-SNAPSHOT.jar, containing the entities.
openjpa.AutoDetach=commit
openjpa.DetachState=fgs
openjpa.QueryCache=false
openjpa.jdbc.SubclassFetchMode=none
openjpa.jdbc.EagerFetchMode=none
openjpa.MetaDataFactory=jpa(ClasspathScan=case-model-1.1.0-SNAPSHOT.jar)
openjpa.jdbc.SynchronizeMappings=buildSchema(ForeignKeys=false,Indexes=false)
openjpa.Log=DefaultLevel=TRACE
The contents of linx2/hsqldb-memory-case-model-persistence.xml follow.
Note the use of the custom mapping file
linx2/hsqldb-memory-case-model-orm.xml, which is located next to
linx2/hsqldb-memory-case-model-persistence.xml in /configuration.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="case-model">
<provider>
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<mapping-file>hsqldb-memory-case-model-orm.xml</mapping-file>
</persistence-unit>
</persistence>
When I run the application and attempt to persist entities, I get the
following error:
<openjpa-1.2.2-r422266:898935 nonfatal general error>
org.apache.openjpa.persistence.PersistenceException: Table not found
in statement ...
which tells me that the schema is not getting generated. I've
confirmed this in the log -- no create table statements are being
executed.
In the log, I see that Spring is reporting something suspicious that I
think might be related to the problem:
15:00:20.176 [main] INFO
org.springframework.beans.factory.config.PropertiesFactoryBean -
Loading properties file from class path resource
[linx2/hsqldb-memory-openjpa.properties]
15:00:20.236 [main] INFO
org.springframework.orm.jpa.persistenceunit.PersistenceUnitReader -
hsqldb-memory-case-model-persistence.xml should be located inside
META-INF directory; cannot determine persistence unit root URL for
class path resource [linx2/hsqldb-memory-case-model-persistence.xml]
15:00:20.237 [main] INFO
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean -
Building JPA container EntityManagerFactory for persistence unit
'case-model'
So while Spring complains about not being able to determine the PU
root URL, it builds the JPA container EMF for PU "case-model".
Immediately thereafter, OpenJPA says it's looking for
META-INF/orm.xml, even though my mapping file is
linx2/hsqldb-memory-case-model-orm.xml:
3 model TRACE [main] openjpa.Runtime - Setting the following
properties from "?" into configuration: {openjpa.DetachState=fgs,
openjpa.connectionfactory=org.apache.commons.dbcp.basicdatasou...@173a0067,
openjpa.jdbc.SynchronizeMappings=buildSchema(ForeignKeys=false,Indexes=false),
javax.persistence.provider=org.apache.openjpa.persistence.PersistenceProviderImpl,
openjpa.MetaDataFactory=jpa(ClasspathScan=case-model-1.1.0-SNAPSHOT.jar),
openjpa.AutoDetach=commit, openjpa.jdbc.EagerFetchMode=none,
openjpa.classresolver=org.apache.openjpa.persistence.persistenceunitinfoimpl$classresolveri...@2da896a4,
openjpa.jdbc.SubclassFetchMode=none, openjpa.Log=DefaultLevel=TRACE,
openjpa.QueryCache=false, openjpa.Id=case-model}
7 model TRACE [main] openjpa.Runtime - No cache marshaller found
for id org.apache.openjpa.conf.MetaDataCacheMaintenance.
47 model TRACE [main] openjpa.MetaData - Scanning resource
"META-INF/orm.xml" for persistent types.
OpenJPA then seems to startup ok, correctly identifying the database
and emitting the usual warning about registering a ClassTransformer,
but with no mention of hsqldb-memory-case-model-persistence.xml or
hsqldb-memory-case-model-orm.xml.
Later, OpenJPA appears to be finding my entities ok and building
metadata from them:
11710 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - Initial connection autoCommit: true, holdability:
1, TransactionIsolation: 2
11713 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - <t 922745441, conn 0> [0 ms] close
11737 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - DataSource connection setAutoCommit to "true"
11738 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - <t 922745441, conn 0> [0 ms] close
11760 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- Scanning resource "META-INF/orm.xml" for persistent types.
11761 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- parsePersistentTypeNames() found [].
11761 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- Found 0 classes with metadata in 1 milliseconds.
11856 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- Processing registered persistence-capable class "class
org.piercecountywa.linx.casemanagement.model.SpecialIdentificationProcedure".
...
At the end of the transaction, I see the following in the log. Note
the unexpected message about parsing class java.lang.String:
...
17096 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- Resolving field
"org.piercecountywa.linx.casemanagement.model.vic...@907194328.incident".
17126 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.MetaData
- Parsing class "java.lang.String".
17133 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0] openjpa.Query -
Executing query: select d from SuperiorCourtDivision d where
d.ajc$interField$org_piercecountywa_linx_casemanagement_model_aspects_NamedMixin$org_piercecountywa_linx_casemanagement_model_aspects_NamedMixin$IntroducedNamed$name
= 'Criminal Division 1'
17173 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - <t 922745441, conn 535160945> [0 ms] rollback
17174 case-model TRACE
[casews-refid-6e511aa0-062a-4564-80a0-8c8c9c969b61-0]
openjpa.jdbc.JDBC - <t 922745441, conn 0> [0 ms] close
I also noticed that OpenJPA seems to be ignoring the mapping
information on fields in entities in case-model-1.1.0-SNAPSHOT.jar.
Can anyone help me here please?
Thanks,
Matthew
--
mailto:[email protected]
skype:matthewadams12
yahoo:matthewadams
aol:matthewadams12
google-talk:[email protected]
msn:[email protected]
http://matthewadams.me
http://www.linkedin.com/in/matthewadams