【问题标题】:Spring+ Hibernate :How to map single session factory in multiple modules (deployed as jar)Spring+ Hibernate:如何在多个模块中映射单个会话工厂(部署为 jar)
【发布时间】:2013-09-25 01:30:31
【问题描述】:

我目前正在研究 Spring + Struts2 和 Hibernate,我的要求是:

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

    <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 文件的路径,请参见下面的代码:

<property name="mappingJarLocations">
<list>
   <value>WEB-INF/lib/subModule.jar</value>
</list>
</property>

上述所有 .hbm 和 DAO/DbSession 类都存在于 Master 模块中。现在我想在部署为 jar 的子模块中使用这个 '''sessionFactoryErik'''。所以为此我在子模块中创建了另一个xml文件,它将参考上面的'''sessionFactoryErik''',并将具有这个模块特定的.hbm和DAO/DbSession的映射。参考以下代码:

 <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>   

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

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)模块。

谢谢。 塔潘

【问题讨论】:

  • 类 org.springframework.orm.hibernate4.LocalSessionFactoryBean 没有名为 sessionFactoryErik 的属性。

标签: spring hibernate struts2


【解决方案1】:

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

<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="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>

【讨论】:

  • 嗨KyelJmD,我已经添加了当我在下面的答案中尝试你的建议时发生的事情,请看一下并提出建议。谢谢。
  • 您好 KyelJmd,我尝试了您的解决方案,但没有成功。我收到以下错误:原因:java.lang.IllegalStateException:无法将类型 [org.hibernate.internal.SessionFactoryImpl] 的值转换为属性“dataSource”所需的类型 [javax.sql.DataSource]:没有匹配的编辑器或转换策略发现于...。然后将属性 ref 从 sessionFactoryErik 更改为在主文件中定义的 dataSourceErik,它在启动时没有给出任何错误,但是当我运行应用程序并尝试点击 DB 时,它给了我以下错误:org.hibernate .HibernateException: No Session found for current thread at...
【解决方案2】:

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

所以你应该指定 org.hibernate.internal.SessionFactoryImpl 或其超类

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

参考。

【讨论】:

    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多