天天看点

Maven 跨项目调用persistence.xml动态配置文件

   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。

Maven 跨项目调用persistence.xml动态配置文件

    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>的下一行。

Maven 跨项目调用persistence.xml动态配置文件
Maven 跨项目调用persistence.xml动态配置文件

这样,就可以自动检测sop-common-0.0.1-SNAPSHOT.jar包里的实体类。

    5.<jar-file>变量

上一步骤的<jar-file>的参数是jar包的名字,如果有一天jar包的名字变了,还要在这里手动改,挺麻烦。

所以我做了些改动,如下,让persistence.xml的<jar-file>指向persistence.xml-process.xml然后指向父级pom.xml中的参数。

Maven 跨项目调用persistence.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结构如下:

Maven 跨项目调用persistence.xml动态配置文件
Maven 跨项目调用persistence.xml动态配置文件

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部分内容如下:

Maven 跨项目调用persistence.xml动态配置文件

在sop项目里找到父级pom.xml并在其中的jboss7profile的properties里添加:

<jar.file>${parent.artifactId}-common-${version}.jar</jar.file>
           
Maven 跨项目调用persistence.xml动态配置文件
Maven 跨项目调用persistence.xml动态配置文件

    9.激活resources-processor

在sop-database项目单击右键—>maven—>select maven profiles, 勾选刚才的resources-processor。

Maven 跨项目调用persistence.xml动态配置文件

然后clean projet:

Maven 跨项目调用persistence.xml动态配置文件

继续阅读