Spring Hibernate:如何在多个模块中映射单个会话工厂(部署为jar)

Spring+ Hibernate :How to map single session factory in multiple modules (deployed as jar)

我目前正在开发Spring Struts2和Hibernate,我的要求是:

  • 我有Master模块,它将与系统中的所有其他模块(部署为Jar)共享数据库连接。
  • 所有特定于模块的.hbm和持久性类将存在于模块本身中
    因此,例如,我的主模块将具有Hibernate连接文件(通过spring)和所有.hbm映射文件,以下是通过Spring建立的Hibernate连接的示例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <bean id="dataSourceErik" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="testWhileIdle" value="true" />
      <property name="minEvictableIdleTimeMillis" value="120000" />
      <property name="timeBetweenEvictionRunsMillis" value="30000" />
    </bean>
    <bean id="sessionFactoryErik"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSourceErik" />
      <property name="hibernateProperties">
        <value>
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
            hibernate.generate_statistics=true
            hibernate.show_sql=false
            hibernate.jdbc.batch_size=10
            hibernate.bytecode.use_reflection_optimizer=true
        hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider                hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
            hibernate.cache.use_second_level_cache=true
            hibernate.cache.use_query_cache=true
            net.sf.ehcache.configurationResourceName=configuration/ehcache.xml
        </value>
      </property>

      <property name="mappingLocations">
        <list>
            <value>classpath:configuration/hibernate/Abc.hbm.xml</value>
            <value>classpath:configuration/hibernate/Xyz.hbm.xml</value>
       </list>
      </property>        
    </bean>
    <bean id="AbcActionDAO" class="au.com.master.persistance.dao.AbcDbSession">
        <constructor-arg ref="sessionFactoryErik" />
    </bean>
    <bean id="XyzActionTypeDAO"class="au.com.master.persistance.dao.XyzDbSession">
        <constructor-arg ref="sessionFactoryErik" />
    </bean>
  • 如果我在上面的xml中添加以下代码,则可以访问'''sessionFactory'''并可以与数据库连接。当我给出已部署的subModule jar文件的路径时,请参见以下代码:

    1
    2
    3
    4
    5
    <property name="mappingJarLocations">
    <list>
       <value>WEB-INF/lib/subModule.jar</value>
    </list>
    </property>

    .hbm和DAO / DbSession类以上均存在于主模块中。现在,我想在部署为jar的Sub模块中使用此'''sessionFactoryErik'''。因此,为此我在Sub模块中创建了另一个xml文件,该文件将引用上述'''sessionFactoryErik'''并将具有该模块特定.hbm和DAO / DbSession的映射。请参阅以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     <bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         <property name="sessionFactoryErik" ref="sessionFactoryErik" />
         <property name="mappingLocations">
            <list>
                <value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
            </list>
          </property>        
     </bean>

     <bean id="testActionDAO" class="au.com.java.subModule.persistance.dao.DddActionDbSession">
        <constructor-arg ref="sessionFactoryMonitor" />
    </bean>

    如果我部署了项目并重新启动服务器,则出现以下错误。

    1
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactoryMonitor' defined in URL [jar:file:/home/developer/Project/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/webapps/erik/WEB-INF/lib/erik-monitor-1.0-SNAPSHOT.jar!/configuration/spring-monitor-dao.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'sessionFactoryErik' of bean class [org.springframework.orm.hibernate4.LocalSessionFactoryBean]: Bean property 'sessionFactoryErik' is not writable or has an invalid setter method.

    有人可以帮我吗?我如何才能在子模块中获得相同的会话对象,因为只有主模块才能建立连接,因为它将不了解其已部署(部署为jar)模块。

    谢谢。
    Tapan


    org.springframework.orm.hibernate4.LocalSessionFactoryBean没有名为sessionFactoryErik的属性。我猜您正在将数据源注入LocalSessionFactoryBean。如果是这样,请更改此

    1
    2
    3
    4
    5
    6
    7
    8
    <bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         <property name="sessionFactoryErik" ref="sessionFactoryErik" />
         <property name="mappingLocations">
            <list>
                <value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
            </list>
          </property>        
     </bean>

    对此

    1
    2
    3
    4
    5
    6
    7
    8
     <bean id="sessionFactoryMonitor" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         <property name="dataSource" ref="sessionFactoryErik" />
         <property name="mappingLocations">
            <list>
                <value>classpath:configuration/hibernate/DDDType.hbm.xml</value>
            </list>
          </property>        
     </bean>


    sessionFactoryErik bean返回org.hibernate.internal.SessionFactoryImpl对象,

    因此您应该指定org.hibernate.internal.SessionFactoryImpl或其父类

    (SessionFactory)输入au.com.master.persistance.dao.XyzDbSession构造函数

    参考。