1.場景
由于業務原因,需要把common項目中的persistence.xml移至database項目中,并且persistence.xml的部分變量是調用了父項目的父級pom.xml的參數。
2.項目結構
建立了3個項目來示範。
-sop:maven父項目,負責連接配接所有子項目(子子產品),含父級pom.xml。
-sop-common:子項目,包含實體類 EntityClient.java
-sop-database:子項目,包含與資料庫操作的相關。
此時已把sop-common中的persistence.xml移至sop-database。
3.問題
用maven建構項目,整個項目被打包成一個ear包, 每個子項目會打包成獨立的jar包。
簡化結構圖:
---sop.ear
--sop-common-0.0.1-SNAPSHOT.jar
--sop-database-0.0.1-SNAPSHOT.jar
進行測試時,會發現EntityClient.java無法調用sop-database中的persistence.xml。那麼問題則是,實體類如何與跨項目的persistence.xml建立聯系?
4.方案
https://stackoverflow.com/questions/4073635/sharing-a-persistence-unit-across-components-in-a-ear-file
這是我在stackoverflow搜到的方案之一,感覺也是最簡單的。就是在persistence.xml加一條<jar-file>, 我把這個加在<jta-data-source>的下一行。
這樣,就可以自動檢測sop-common-0.0.1-SNAPSHOT.jar包裡的實體類。
5.<jar-file>變量
上一步驟的<jar-file>的參數是jar包的名字,如果有一天jar包的名字變了,還要在這裡手動改,挺麻煩。
是以我做了些改動,如下,讓persistence.xml的<jar-file>指向persistence.xml-process.xml然後指向父級pom.xml中的參數。
6.pom.xml (sop-database)
在sop-database中的pom.xml添加profile
直接上代碼:
<profile>
<!-- This profile is used to change settings in function of targeted server.-->
<id>resources-processor</id>
<activation>
<property>
<name>!m2e.version</name>
</property>
</activation>
<properties>
<!-- Directories -->
<resources-directory>/</resources-directory>
<resources-source>src/main/resources${resources-directory}</resources-source>
<resources-processor>src/main/resources-processor/${target_server}/</resources-processor>
<resources-output>classes${resources-directory}</resources-output>
<!-- Files to process -->
<processor-suffix>-process.xml</processor-suffix>
<persistence-file>persistence.xml</persistence-file>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.2.0.Final</version>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.google.code.maven-config-processor-plugin</groupId>
<artifactId>config-processor-maven-plugin</artifactId>
<version>2.5</version>
<configuration>
<transformations>
<transformation>
<input>${resources-source}META-INF/${persistence-file}</input>
<output>${resources-output}META-INF/${persistence-file}</output>
<config>${resources-processor}META-INF/${persistence-file}${processor-suffix}</config>
</transformation>
</transformations>
<!-- Here is the mapping -->
<namespaceContexts>
<p>http://java.sun.com/xml/ns/persistence</p>
</namespaceContexts>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
7.persistence.xml-process.xml
在sop-database建立resources-processor等。jboss7是運作的server。
現sop-database的src結構如下:
persistence.xml-process.xml 的内容如下:
<processor xsi:noNamespaceSchemaLocation="https://maven-config-processor-plugin.googlecode.com/svn/tags/config-processor-maven-plugin-2.5/src/etc/schema/transformation-2.2.xsd">
<modify>
<name>//p:persistence-unit[@name='defaultPersistenceUnit']//p:jta-data-source</name>
<value>
<![CDATA[
<jta-data-source>${jpa.datasource}</jta-data-source>
]]>
</value>
</modify>
<modify>
<name>//p:persistence-unit[@name='defaultPersistenceUnit']//p:jar-file</name>
<value>
<![CDATA[
<jar-file>${jar.file}</jar-file>
]]>
</value>
</modify>
</processor>
<name>中的 p:persistence-unit 對應于 persistence.xml裡的<persistence-unit>, p:jar-file 對應于<jar-file>。
${jar.file}中的jar.file是我随便命名的,與父級pom.xml 定義的标簽名一緻。
8.父級pom.xml (sop)
父級pom.xml部分内容如下:
在sop項目裡找到父級pom.xml并在其中的jboss7profile的properties裡添加:
<jar.file>${parent.artifactId}-common-${version}.jar</jar.file>
9.激活resources-processor
在sop-database項目單擊右鍵—>maven—>select maven profiles, 勾選剛才的resources-processor。
然後clean projet: