tomcat 上使用jpa

http://www.liferay.com/zh_CN/community/wiki/-/wiki/Main/JPA+on+Tomcat

How to configure on Tomcat

1. copy lib/development/spring-instrument-tomcat.jar to tomcat/lib/ext
2. Edit conf/Catalina/localhost/ROOT.xml and add this line in the "Context" element.

    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
3. Delete hibernate3.jar from WEB-INF/lib
4. Copy to WEB-INF/lib
    persistence.jar
    eclipselink.jar
5. configure portal-ext.properties

    1. persistence.provider=jpa
    2. 
transaction.isolation.portal=-1    # Notice that the value is negative 1 which means default
    3. transaction.isolation.counter=-1  

Spring提供了大量用于不同环境的 LoadTimeWeaver 实现类, 允许 ClassTransformer 实例能够仅用于每个classloader ,而不是每个虚拟机。

接下来的一节将讨论在Tomcat以及使用Spring的VM代理情况下的典型JPA织入配置。关于设置常用加载时织入的详细内容, 请参见AOP一章中的第 6.8.4.5 节 “Spring配置”一节,它涵盖了Tomcat、VM代理以及WebLogic、OC4J、GlassFish和Resin。

12.6.1.3.1. Tomcat(5.0以上)加载时的织入配置
Apache Tomcat 缺省的ClassLoader(类装载器)并不支持类的切换, 但是它允许使用用户自定义的类装载器。Spring提供了 TomcatInstrumentableClassLoader 类 (在org.springframework.instrument.classloading.tomcat 包中),这个类继承自Tomcat的类装载器 (WebappClassLoader)并且允许JPA ClassTransformer 的实例来“增强”所有由它加载的类。 简单说,JPA转化器(JPA transformer)仅仅在(使用 TomcatInstrumentableClassLoader 的)特定web应用程序中才能被使用。

为使用用户自定义的类装载器:

将 spring-tomcat-weaver.jar 复制到 $CATALINA_HOME/server/lib 下 (其中$CATALINA_HOME 表示Tomcat的安装路径)。

通过修改web application context使Tomcat使用用户自定义的类装载器(而不是默认的类装载器):

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
Tomcat 5.0.x 和 5.5.x 系列支持多个上下文路径(context locations): 服务器配置文件($CATALINA_HOME/conf/server.xml), 默认的上下文配置($CATALINA_HOME/conf/context.xml)会影响所有被部署的web应用程序、 单独部署在Server端的web应用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my- webapp-context.xml) 或者与web应用程序一起(your-webapp.war/META-INF/context.xml)。从效率的角度说, 我们推荐在web-app的内部配置的方式,因为仅仅使用JPA的应用程序会使用用户自定义的类装载器。 更多具体有关可用的上下文路径的内容请参见Tomcat 5.x的文档。

注意,5.5.20之前的版本有一个XML配置解析的bug,造成 server.xml 中无法使用Loader标签,无论是否指定了classloader,也不管这个classloader是官方的还是自定义的。

        
如果你正在使用的是Tomcat 5.5.20以上的版本,就可以将useSystemClassLoaderAsParent设置成        false来解决这个问题:

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
            useSystemClassLoaderAsParent="false"/>
</Context>
将spring-tomcat-weaver.jar复制到$CATALINA_HOME/lib (where $CATALINA_HOME表示Tomcat安装根目录的位置)。

通过编辑web应用程序上下文文件,使Tomcat使用自定义的ClassLoader(而不是默认的ClassLoader):

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
Tomcat 6.0.x (类似于5.0.x/5.5.x)系列支持几种上下文路径:(context locations): 服务器配置文件($CATALINA_HOME/conf/server.xml), 默认的上下文配置($CATALINA_HOME/conf/context.xml)会影响所有被部署的web应用程序、 单独部署在Server端的web应用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my- webapp-context.xml) 或者与web应用程序一起(your-webapp.war/META-INF/context.xml)。从效率的角度说, 我们推荐在web-app的内部配置的方式,因为仅仅使用JPA的应用程序会使用用户自定义的类装载器。 更多具体有关可用的上下文路径的内容请参见Tomcat 5.x documentation。

Tomcat 5.0.x/5.5.x

Tomcat 6.0.x

所有Tomcat版本所需的最后一步,是在配置LocalContainerEntityManagerFactoryBean的时,使用 相应的LoadTimeWeaver:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
  </property>
</bean>
利用这种方法,依赖工具的JPA应用程序无需代理就可以在Tomcat上运行。这在宿主应用程序依赖不同的JPA实现时尤为重要, 因为JPA转化器只适用于ClassLoader级别,它们之间是彼此隔离的。

注意
如果Tomcat使用TopLink作为JPA提供者,请将核心的toplink jar包放在$CATALINA_HOME/shared/lib文件夹中,而不再放到war中。

12.6.1.3.2. 使用VM代理的全局加载时织入
对于需要类工具,同时现有的LoadTimeWeaver实现不提供这种支持的环境,JDK代理是唯一的解决方案。对于这种情况,Spring提 供了 需要特定于Spring(但非常常用)的VM代理(spring-agent.jar)的InstrumentationLoadTimeWeaver:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
  </property>
</bean>
请注意在启动虚拟机时,同时启动Spring代理,方法是提供下列JVM选项:

-javaagent:/path/to/spring-agent.jar
12.6.1.3.3. 上下文范围内的加载时织入配置
自Spring 2.5,可以使用context:load-time-weaver元素来配置 上下文范围的LoadTimeWeaver了。这种“全局”织入器由所有JPA LocalContainerEntityManagerFactoryBeans自动拣选。

这是配置加载时织入器的推荐方法,提供平台(ebLogic, OC4J, GlassFish, Tomcat, Resin, VM agent)的自动检测,以及织入器到所有织入器知道的bean的自动传播。

<context:load-time-weaver/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    ...
</bean>
关于如何建立常用加载时织入的详细内容,请参见第 6.8.4.5 节 “Spring配置”一节,它涵盖了 Tomcat、VM代理,以及WebLogic, OC4J, GlassFish和Resin。

12.6.1.4. 处理多持久化单元
对于那些依靠多个持久化单元位置(例如存放在classpath中的多个jar中)的应用程序, Spring提供了作为中央仓库的PersistenceUnitManager, 避免了持久化单元查找过程(的潜在开销)。缺省实现允许指定多个位置 (默认情况下classpath会搜索META-INF/persistence.xml文件),它们会被解析然后通过持久化单元名称被获取:

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  <property name="persistenceXmlLocation">
    <list>
     <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
     <value>classpath:/my/package/**/custom-persistence.xml</value>
     <value>classpath*:META-INF/persistence.xml</value>
    </list>
  </property>
  <property name="dataSources">
   <map>
    <entry key="localDataSource" value-ref="local-db"/>
    <entry key="remoteDataSource" value-ref="remote-db"/>
   </map>
  </property>
  <!-- if no datasource is specified, use this one -->
  <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitManager" ref="pum"/>
</bean>
要注意的是,缺省实现允许在将持久化单元信息传入JPA provider之前用 PersistenceUnitPostProcessor(它允许选择持久化单元)修改它们, 传入的过程可以是通过属性声明式地传入(影响其中所有的单元)或编程式地传入。 如果没有指定persistenceUnitManager,LocalContainerEntityManagerFactoryBean 会创建一个并在内部使用它。

猜你喜欢

转载自anole1982.iteye.com/blog/1662173