Hi,
I think this is really more of a Spring question than an OpenJPA question --
Spring is (presumably) using the JPA-provided bootstrapping API calls, which
don't allow for non-standard persistence.xml file locations.
Once you get your persistence.xml file loaded properly, you'll have a lot more
flexibility in terms of telling OpenJPA where to load resources from etc.
Depending on how the Spring PU creation code is implemented, you might be able
to have some success with your current approach by *not* specifying a
persistence.xml resource location, and instead providing one in the appropriate
OpenJPA property (I'm not sure what that'd be off the top of my head).
However.... what about putting all your persistence.xml files into the standard
resource location, and instead using different persistence unit names for each
store? You could do this by putting a number of directories (or jars) into the
classpath, and set up each to have a persistence.xml file. Then, each one of
those could point to a differently-named orm.xml file stored in the same dir /
jar.
-Patrick
On Apr 28, 2010, at 3:48 PM, Matthew Adams wrote:
> 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
--
Patrick Linskey
202 669 5907