I followed this tutorial and set off to add another persistence unit pointing to a separate database. It should not share broadleaf own entities. So...
The core project now holds applicationContext.xml with these new beans:
<!-- New data source to our DB -->
<bean id="blMergedDataSources" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="jdbc/in1" value-ref="in1DS" />
</map>
</property>
</bean>
<bean id="entityManagerFactoryIn1PU"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="blJpaVendorAdapter" />
<property name="persistenceUnitManager" ref="blPersistenceUnitManager" />
<property name="persistenceUnitName" value="in1PU" />
</bean>
<bean id="blPersistenceUnitManager" class="org.broadleafcommerce.common.extensibility.jpa.MergePersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:/META-INF/in1_persistence.xml</value>
</list>
</property>
<property name="persistenceUnitPostProcessors">
<list>
<bean
class="org.broadleafcommerce.common.extensibility.jpa.JPAPropertiesPersistenceUnitPostProcessor">
<property name="persistenceUnitProperties">
<map>
<entry key="in1PU.hibernate.dialect" value="${in1PU.hibernate.dialect}" />
<entry key="in1PU.hibernate.hbm2ddl.auto" value="${in1PU.hibernate.hbm2ddl.auto}"/>
<entry key="in1PU.hibernate.show_sql" value="${in1PU.hibernate.show_sql}"/>
<entry key="in1PU.hibernate.cache.use_second_level_cache" value="${in1PU.hibernate.cache.use_second_level_cache}"/>
<entry key="in1PU.hibernate.cache.use_query_cache" value="${in1PU.hibernate.cache.use_query_cache}"/>
<entry key="in1PU.hibernate.hbm2ddl.import_files" value="${in1PU.hibernate.hbm2ddl.import_files}"/>
<entry key="in1PU.hibernate.hbm2ddl.import_files_sql_extractor" value="${in1PU.hibernate.hbm2ddl.import_files_sql_extractor}"/>
</map>
</property>
</bean>
</list>
</property>
</bean>
The core project also has file /META-INF/in1_persistance.xml with the following:
<persistence-unit name="in1PU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/in1</non-jta-data-source>
<exclude-unlisted-classes/>
</persistence-unit>
Properties for this persistance unit are very similar to blPU ones, for example:
in1PU.hibernate.hbm2ddl.auto=create-drop
in1PU.hibernate.dialect=com.in1.hibernate.SubSQLServer2008Dialect
In the admin new resource is added to \admin\src\main\webapp\META-INF\context.xml:
<Resource name="jdbc/in1" [....] />
Also in admin, new jndi resource is set in \admin\src\main\webapp\WEB-INF\jetty-env.xml:
<New id="in1DS" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jdbc/in1</Arg>
<Arg>
<New class="org.apache.commons.dbcp.BasicDataSource">
<Set name="driverClassName">net.sourceforge.jtds.jdbc.Driver</Set>
<Set name="url">jdbc:jtds:sqlserver://localhost:1433;databaseName=DB2</Set>
<Set name="username">xyz</Set>
<Set name="password">xyz</Set>
</New>
</Arg>
</New>
And to applicationContext-datasource.xml, the following was added <jee:jndi-lookup id="in1DS" jndi-name="jdbc/in1"/>
The application starts up and fails with the following error message:
[artifact:mvn] javax.persistence.PersistenceException: [PersistenceUnit: in1PU] Unable to build EntityManagerFactory
[...]
[artifact:mvn] Caused by:
[artifact:mvn] org.hibernate.AnnotationException: @OneToOne or @ManyToOne on org.broadleafcommerce.core.catalog.domain.ProductImpl.defaultCategory references an unknown entity: org.broadleafcommerce.core.catalog.domain.CategoryImpl
[artifact:mvn] at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:109)
I am wondering why this new persistence unit looks up ProductImpl class? It is not listed for it to use (in in1_persistence.xml no classes as listed, and <exclude-unlisted-classes/>
is on). It surely can't see CategoryImpl entity.... What I am doing wrong here?
I have answered my own question after debugging org.hibernate.ejb.Ejb3Configuration a bit.
In persistence.xml, it is not enough to have just <exclude-unlisted-classes/>
. The property hibernate.archive.autodetection
must also be set. Basically it cannot be null. The valid values in there are "class"
, "hbm"
or "class,hbm"
, which we don't want, therefore the value can be set to anything, and "false"
is doing fine job.
So the correct minimal persistence.xml is:
<persistence-unit name="in1PU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>jdbc/in1</non-jta-data-source>
<exclude-unlisted-classes/>
<properties>
<property name="hibernate.archive.autodetection" value="false" />
</properties>
</persistence-unit>
Hope this helps.