`

osgi spring hibernate

    博客分类:
  • OSGI
阅读更多

 先来说说整合Hibernate的关键之处。其实用OSGi整合Hibernate很简单,但要通过Bundle方式做到可以扩展新的持久化层面的东西(比如添加新的表和操作)就比较费事了。因为Hibernate在初始化时根据注册的实体类创建SessionFactory,这样当有新的实体类添加进来时就要创建新的SessionFactory,这样系统中出现两个甚至多个SessionFatory会导致一系列的问题。显然整合Hibernate关键就是解决实体类注册与SessionFactory创建的问题。
        我的具体思路如下。
        首先将Hibernate单独多为一个Bundle(wanged_commons_hibernate)以便提供其他Bundle所需类包。
        然后建立一个用于提供实体注册接口的Bundle(wanged_core_persistent_entity_register),代码如下:

java 代码
 
  1. package wanged.core.persistent.entity;  
  2.   
  3. @SuppressWarnings("unchecked")  
  4. public interface EntityRegister {  
  5.   
  6.     /** 
  7.      * 注册Hibernate的实体Class 
  8.      * @return 
  9.      */  
  10.     Class[] register();  
  11.      
  12. }  

       建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。
LocalSessionFactoryBean的代码:

java 代码
 
  1. package wanged.core.persistent;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Properties;  
  5.   
  6. import javax.sql.DataSource;  
  7.   
  8. import org.hibernate.ConnectionReleaseMode;  
  9. import org.hibernate.HibernateException;  
  10. import org.hibernate.SessionFactory;  
  11. import org.hibernate.cfg.Configuration;  
  12. import org.hibernate.cfg.Environment;  
  13. import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;  
  14. import org.springframework.orm.hibernate3.AbstractSessionFactoryBean;  
  15. import org.springframework.orm.hibernate3.SpringSessionContext;  
  16. import org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider;  
  17.   
  18. import wanged.core.persistent.entity.EntityRegister;  
  19.   
  20. @SuppressWarnings("unchecked")  
  21. public class LocalSessionFactoryBean extends AbstractSessionFactoryBean {  
  22.   
  23.     private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal();  
  24.   
  25.     private Properties hibernateProperties;  
  26.   
  27.     private HashMapnew HashMap
  28.   
  29.     private Configuration configuration;  
  30.   
  31.     public static DataSource getConfigTimeDataSource() {  
  32.         return (DataSource) configTimeDataSourceHolder.get();  
  33.     }  
  34.   
  35.     /** 
  36.      * 注册Entity的Class数组 
  37.      *  
  38.      * @param er 
  39.      */  
  40.     @SuppressWarnings("unchecked")  
  41.     public void setEntityRegister(EntityRegister[] erArr) {  
  42.         for (EntityRegister er : erArr) {  
  43.             this.addEntityRegister(er);  
  44.         }  
  45.   
  46.     }  
  47.       
  48.     @SuppressWarnings("unchecked")  
  49.     public void setEntityRegister(EntityRegister er) {  
  50.         this.addEntityRegister(er);  
  51.     }  
  52.   
  53.     private void addEntityRegister(EntityRegister er){  
  54.         // TODO:对registerClass()中取得的数组进行验证  
  55.         this.entityClasses.put(er, er.register());  
  56.     }  
  57.       
  58.     /** 
  59.      * 卸载Entity的Class数组 
  60.      *  
  61.      * @param er 
  62.      */  
  63.     public void unsetEntityRegister(EntityRegister er) {  
  64.         this.entityClasses.remove(er);  
  65.   
  66.         // TODO:重新初始化SessionFactory  
  67.   
  68.     }  
  69.   
  70.     public void setHibernateProperties(Properties hibernateProperties) {  
  71.         this.hibernateProperties = hibernateProperties;  
  72.     }  
  73.   
  74.     public Properties getHibernateProperties() {  
  75.         if (this.hibernateProperties == null) {  
  76.             this.hibernateProperties = new Properties();  
  77.         }  
  78.         return this.hibernateProperties;  
  79.     }  
  80.   
  81.     @SuppressWarnings("unchecked")  
  82.     protected SessionFactory buildSessionFactory() {  
  83.         Configuration config = new Configuration();  
  84.         DataSource dataSource = getDataSource();  
  85.         if (dataSource != null) {  
  86.             configTimeDataSourceHolder.set(dataSource);  
  87.         }  
  88.   
  89.         try {  
  90.             config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());  
  91.   
  92.             if (isExposeTransactionAwareSessionFactory()) {  
  93.                 config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());  
  94.             }  
  95.   
  96.             if (this.hibernateProperties != null) {  
  97.                 config.addProperties(this.hibernateProperties);  
  98.             }  
  99.   
  100.             if (dataSource != null) {  
  101.                 boolean actuallyTransactionAware = (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy);  
  102.                 config.setProperty(Environment.CONNECTION_PROVIDER, actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class  
  103.                                 .getName() : LocalDataSourceConnectionProvider.class.getName());  
  104.             }  
  105.   
  106.             // 添加Entity的类  
  107.             for (Class[] cArr : this.entityClasses.values()) {  
  108.                 for (Class c : cArr) {  
  109.                     config.addClass(c);  
  110.                 }  
  111.             }  
  112.             this.configuration = config;  
  113.             return config.buildSessionFactory();  
  114.         } finally {  
  115.             if (dataSource != null) {  
  116.                 configTimeDataSourceHolder.set(null);  
  117.             }  
  118.         }  
  119.     }  
  120.   
  121.     /** 
  122.      * Return the Configuration object used to build the SessionFactory. Allows 
  123.      * access to configuration metadata stored there (rarely needed). 
  124.      *  
  125.      * @throws IllegalStateException 
  126.      *             if the Configuration object has not been initialized yet 
  127.      */  
  128.     public final Configuration getConfiguration() {  
  129.         if (this.configuration == null) {  
  130.             throw new IllegalStateException("Configuration not initialized yet");  
  131.         }  
  132.         return this.configuration;  
  133.     }  
  134.   
  135.     public void destroy() throws HibernateException {  
  136.         DataSource dataSource = getDataSource();  
  137.         if (dataSource != null) {  
  138.             configTimeDataSourceHolder.set(dataSource);  
  139.         }  
  140.         try {  
  141.             super.destroy();  
  142.         } finally {  
  143.             if (dataSource != null) {  
  144.                 configTimeDataSourceHolder.set(null);  
  145.             }  
  146.         }  
  147.     }  
  148. }  

LocalDataSourceConnectionProvider的代码:

java 代码
引用 "实体注册" 服务需要在我们的实体Bundle中实现,现在已经搭好了架子,下一步就需要创建自己的实体Bundle和数据库操作的Bundle。由于这个Blog保存时经常保存不住,需要重写,所以我尽可能的将其划分开来写。

 
  1. package wanged.core.persistent;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.SQLException;  
  5. import java.util.Properties;  
  6.   
  7. import javax.sql.DataSource;  
  8.   
  9. import org.hibernate.HibernateException;   先来说说整合Hibernate的关键之处。其实用OSGi整合Hibernate很简单,但要通过Bundle方式做到可以扩展新的持久化层面的东西(比如添加新的表和操作)就比较费事了。因为Hibernate在初始化时根据注册的实体类创建SessionFactory,这样当有新的实体类添加进来时就要创建新的SessionFactory,这样系统中出现两个甚至多个SessionFatory会导致一系列的问题。显然整合Hibernate关键就是解决实体类注册与SessionFactory创建的问题。 我的具体思路如下。 首先将Hibernate单独多为一个Bundle(wanged_commons_hibernate)以便提供其他Bundle所需类包。 然后建立一个用于提供实体注册接口的Bundle(wanged_core_persistent_entity_register),代码如下: java 代码 package wanged.core.persistent.entity; @SuppressWarnings("unchecked") public interface EntityRegister { /** * 注册Hibernate的实体Class * @return */ Class[] register(); } 建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。类LocalSessionFactoryBean的代码: java 代码 package wanged.core.persistent; import java.util.HashMap; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.ConnectionReleaseMode; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.orm.hibernate3.AbstractSessionFactoryBean; import org.springframework.orm.hibernate3.SpringSessionContext; import org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider; import wanged.core.persistent.entity.EntityRegister; @SuppressWarnings("unchecked") public class LocalSessionFactoryBean extends AbstractSessionFactoryBean { private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal(); private Properties hibernateProperties; private HashMapnew HashMap private Configuration configuration; public static DataSource getConfigTimeDataSource() { return (DataSource) configTimeDataSourceHolder.get(); } /** * 注册Entity的Class数组 * * @param er */ @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister[] erArr) { for (EntityRegister er : erArr) { this.addEntityRegister(er); } } @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister er) { this.addEntityRegister(er); } private void addEntityRegister(EntityRegister er){ // TODO:对registerClass()中取得的数组进行验证 this.entityClasses.put(er, er.register()); } /** * 卸载Entity的Class数组 * * @param er */ public void unsetEntityRegister(EntityRegister er) { this.entityClasses.remove(er); // TODO:重新初始化SessionFactory } public void setHibernateProperties(Properties hibernateProperties) { this.hibernateProperties = hibernateProperties; } public Properties getHibernateProperties() { if (this.hibernateProperties == null) { this.hibernateProperties = new Properties(); } return this.hibernateProperties; } @SuppressWarnings("unchecked") protected SessionFactory buildSessionFactory() { Configuration config = new Configuration(); DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString()); if (isExposeTransactionAwareSessionFactory()) { config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } if (this.hibernateProperties != null) { config.addProperties(this.hibernateProperties); } if (dataSource != null) { boolean actuallyTransactionAware = (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy); config.setProperty(Environment.CONNECTION_PROVIDER, actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class .getName() : LocalDataSourceConnectionProvider.class.getName()); } // 添加Entity的类 for (Class[] cArr : this.entityClasses.values()) { for (Class c : cArr) { config.addClass(c); } } this.configuration = config; return config.buildSessionFactory(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } /** * Return the Configuration object used to build the SessionFactory. Allows * access to configuration metadata stored there (rarely needed). * * @throws IllegalStateException * if the Configuration object has not been initialized yet */ public final Configuration getConfiguration() { if (this.configuration == null) { throw new IllegalStateException("Configuration not initialized yet"); } return this.configuration; } public void destroy() throws HibernateException { DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { super.destroy(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } } 类LocalDataSourceConnectionProvider的代码: java 代码 package wanged.core.persistent; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.HibernateException; import org.hibernate.connection.ConnectionProvider; import org.hibernate.util.JDBCExceptionReporter; public class LocalDataSourceConnectionProvider implements ConnectionProvider { private DataSource dataSource; private DataSource dataSourceToUse; public void configure(Properties props) throws HibernateException { this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource(); if (this.dataSource == null) { throw new HibernateException("No local DataSource found for configuration - " + "dataSource property must be set on LocalSessionFactoryBean"); } this.dataSourceToUse = getDataSourceToUse(this.dataSource); } protected DataSource getDataSourceToUse(DataSource originalDataSource) { return originalDataSource; } public DataSource getDataSource() { return dataSource; } public Connection getConnection() throws SQLException { try { return this.dataSourceToUse.getConnection(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void closeConnection(Connection con) throws SQLException { try { con.close(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void close() { } public boolean supportsAggressiveRelease() { return false; } } 如果你对比其与Spring提供的同名类中的代码,相差不大。下面来看看配置文件,我把Bean的初始化放在bean.xml中: xml 代码 <!-- 本地调试使用连接池--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.gjt.mm.mysql.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/cms" /> <property name="username" value="root" /> <property name="password" value="root" /> <property name="connectionProperties"> <props> <prop key="useUnicode">true</prop> <prop key="characterEncoding">GBK</prop> </props> </property> </bean> <!-- 服务实现类定义 --> <bean id="sessionFactory" class="wanged.core.persistent.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.jdbc.batch_size">20</prop> </props> </property> <property name="dataSource" ref="dataSource" /> <property name="entityRegister" ref="entityRegister" /> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> 而服务与引用的声明放在osgi-service.xml中: xml 代码 <osgi:reference id="entityRegister" interface="wanged.core.persistent.entity.EntityRegister" cardinality="1..n"/> <osgi:service interface="org.hibernate.SessionFactory" ref="sessionFactory" /> <osgi:service interface="org.springframework.transaction.PlatformTransactionManager" ref="txManager" /> 这里的引用 "实体注册" 服务需要在我们的实体Bundle中实现,现在已经搭好了架子,下一步就需要创建自己的实体Bundle和数据库操作的Bundle。由于这个Blog保存时经常保存不住,需要重写,所以我尽可能的将其划分开来写。
    
     
  10. import org.hibernate.connection.ConnectionProvider;  
  11. import org.hibernate.util.JDBCExceptionReporter;  
  12.   
  13. public class LocalDataSourceConnectionProvider implements ConnectionProvider {  
  14.   
  15.     private DataSource dataSource;  
  16.   
  17.     private DataSource dataSourceToUse;  
  18.   
  19.   
  20.     public void configure(Properties props) throws HibernateException {  
  21.         this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource();  
  22.         if (this.dataSource == null) {  
  23.             throw new HibernateException("No local DataSource found for configuration - " +  
  24.                 "dataSource property must be set on LocalSessionFactoryBean");  
  25.         }  
  26.         this.dataSourceToUse = getDataSourceToUse(this.dataSource);  
  27.     }  
  28.   
  29.     protected DataSource getDataSourceToUse(DataSource originalDataSource) {  
  30.         return originalDataSource;  
  31.     }  
  32.   
  33.     public DataSource getDataSource() {  
  34.         return dataSource;  
  35.     }  
  36.   
  37.     public Connection getConnection() throws SQLException {  
  38.         try {  
  39.             return this.dataSourceToUse.getConnection();  
  40.         }  
  41.         catch (SQLException ex) {  
  42.             JDBCExceptionReporter.logExceptions(ex);  
  43.             throw ex;  
  44.         }  
  45.     }  
  46.   
  47.     public void closeConnection(Connection con) throws SQLException {  
  48.         try {  
  49.             con.close();  
  50.         }  
  51.         catch (SQLException ex) {  
  52.             JDBCExceptionReporter.logExceptions(ex);  
  53.             throw ex;  
  54.         }  
  55.     }  
  56.   
  57.     public void close() {  
  58.     }  
  59.   
  60.     public boolean supportsAggressiveRelease() {  
  61.         return false;  
  62.     }  
  63.   
  64. }  

如果你对比其与Spring提供的同名类中的代码,相差不大。
下面来看看配置文件,我把Bean的初始化放在bean.xml中:

xml 代码
 
  1. <!-- 本地调试使用连接池-->  
  2.   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  3.     <property name="driverClassName" value="org.gjt.mm.mysql.Driver" />  
  4.     <property name="url" value="jdbc:mysql://localhost:3306/cms" />  
  5.     <property name="username" value="root" />  
  6.     <property name="password" value="root" />  
  7.     <property name="connectionProperties">  
  8.       <props>  
  9.         <prop key="useUnicode">true</prop>  
  10.         <prop key="characterEncoding">GBK</prop>  
  11.       </props>  
  12.     </property>  
  13.   </bean>  
  14.    
  15.   <!-- 服务实现类定义 -->  
  16.   <bean id="sessionFactory" class="wanged.core.persistent.LocalSessionFactoryBean">  
  17.     <property name="hibernateProperties">  
  18.       <props>  
  19.         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
  20.         <prop key="hibernate.show_sql">false</prop>  
  21.         <prop key="hibernate.cache.use_query_cache">true</prop>  
  22.         <prop key="hibernate.jdbc.batch_size">20</prop>  
  23.       </props>  
  24.     </property>  
  25.     <property name="dataSource" ref="dataSource" />  
  26.     <property name="entityRegister" ref="entityRegister" />  
  27.   </bean>  
  28.   
  29.   <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  30.     <property name="sessionFactory" ref="sessionFactory" />  
  31.   </bean>  

而服务与引用的声明放在osgi-service.xml中:
xml 代码
 
  1. <osgi:reference id="entityRegister"  interface="wanged.core.persistent.entity.EntityRegister" cardinality="1..n"/>    
  2.   
  3. <osgi:service interface="org.hibernate.SessionFactory" ref="sessionFactory" />    
  4.   
  5. <osgi:service interface="org.springframework.transaction.PlatformTransactionManager" ref="txManager" />    
这里的
分享到:
评论
2 楼 wxjiaaa 2009-12-23  
package wanged.core.persistent.entity; @SuppressWarnings("unchecked") public interface EntityRegister { /** * 注册Hibernate的实体Class * @return */ Class[] register(); } 建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。类LocalSessionFactoryBean的代码: java 代码 package wanged.core.persistent; import java.util.HashMap; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.ConnectionReleaseMode; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.orm.hibernate3.AbstractSessionFactoryBean; import org.springframework.orm.hibernate3.SpringSessionContext; import org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider; import wanged.core.persistent.entity.EntityRegister; @SuppressWarnings("unchecked") public class LocalSessionFactoryBean extends AbstractSessionFactoryBean { private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal(); private Properties hibernateProperties; private HashMapnew HashMap private Configuration configuration; public static DataSource getConfigTimeDataSource() { return (DataSource) configTimeDataSourceHolder.get(); } /** * 注册Entity的Class数组 * * @param er */ @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister[] erArr) { for (EntityRegister er : erArr) { this.addEntityRegister(er); } } @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister er) { this.addEntityRegister(er); } private void addEntityRegister(EntityRegister er){ // TODO:对registerClass()中取得的数组进行验证 this.entityClasses.put(er, er.register()); } /** * 卸载Entity的Class数组 * * @param er */ public void unsetEntityRegister(EntityRegister er) { this.entityClasses.remove(er); // TODO:重新初始化SessionFactory } public void setHibernateProperties(Properties hibernateProperties) { this.hibernateProperties = hibernateProperties; } public Properties getHibernateProperties() { if (this.hibernateProperties == null) { this.hibernateProperties = new Properties(); } return this.hibernateProperties; } @SuppressWarnings("unchecked") protected SessionFactory buildSessionFactory() { Configuration config = new Configuration(); DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString()); if (isExposeTransactionAwareSessionFactory()) { config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } if (this.hibernateProperties != null) { config.addProperties(this.hibernateProperties); } if (dataSource != null) { boolean actuallyTransactionAware = (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy); config.setProperty(Environment.CONNECTION_PROVIDER, actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class .getName() : LocalDataSourceConnectionProvider.class.getName()); } // 添加Entity的类 for (Class[] cArr : this.entityClasses.values()) { for (Class c : cArr) { config.addClass(c); } } this.configuration = config; return config.buildSessionFactory(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } /** * Return the Configuration object used to build the SessionFactory. Allows * access to configuration metadata stored there (rarely needed). * * @throws IllegalStateException * if the Configuration object has not been initialized yet */ public final Configuration getConfiguration() { if (this.configuration == null) { throw new IllegalStateException("Configuration not initialized yet"); } return this.configuration; } public void destroy() throws HibernateException { DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { super.destroy(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } } 类LocalDataSourceConnectionProvider的代码: java 代码 package wanged.core.persistent; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.HibernateException; import org.hibernate.connection.ConnectionProvider; import org.hibernate.util.JDBCExceptionReporter; public class LocalDataSourceConnectionProvider implements ConnectionProvider { private DataSource dataSource; private DataSource dataSourceToUse; public void configure(Properties props) throws HibernateException { this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource(); if (this.dataSource == null) { throw new HibernateException("No local DataSource found for configuration - " + "dataSource property must be set on LocalSessionFactoryBean"); } this.dataSourceToUse = getDataSourceToUse(this.dataSource); } protected DataSource getDataSourceToUse(DataSource originalDataSource) { return originalDataSource; } public DataSource getDataSource() { return dataSource; } public Connection getConnection() throws SQLException { try { return this.dataSourceToUse.getConnection(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void closeConnection(Connection con) throws SQLException { try { con.close(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void close() { } public boolean supportsAggressiveRelease() { return false; } }
1 楼 wxjiaaa 2009-12-23  
package wanged.core.persistent.entity; @SuppressWarnings("unchecked") public interface EntityRegister { /** * 注册Hibernate的实体Class * @return */ Class[] register(); } 建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。类LocalSessionFactoryBean的代码: java 代码 package wanged.core.persistent; import java.util.HashMap; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.ConnectionReleaseMode; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.orm.hibernate3.AbstractSessionFactoryBean; import org.springframework.orm.hibernate3.SpringSessionContext; import org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider; import wanged.core.persistent.entity.EntityRegister; @SuppressWarnings("unchecked") public class LocalSessionFactoryBean extends AbstractSessionFactoryBean { private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal(); private Properties hibernateProperties; private HashMapnew HashMap private Configuration configuration; public static DataSource getConfigTimeDataSource() { return (DataSource) configTimeDataSourceHolder.get(); } /** * 注册Entity的Class数组 * * @param er */ @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister[] erArr) { for (EntityRegister er : erArr) { this.addEntityRegister(er); } } @SuppressWarnings("unchecked") public void setEntityRegister(EntityRegister er) { this.addEntityRegister(er); } private void addEntityRegister(EntityRegister er){ // TODO:对registerClass()中取得的数组进行验证 this.entityClasses.put(er, er.register()); } /** * 卸载Entity的Class数组 * * @param er */ public void unsetEntityRegister(EntityRegister er) { this.entityClasses.remove(er); // TODO:重新初始化SessionFactory } public void setHibernateProperties(Properties hibernateProperties) { this.hibernateProperties = hibernateProperties; } public Properties getHibernateProperties() { if (this.hibernateProperties == null) { this.hibernateProperties = new Properties(); } return this.hibernateProperties; } @SuppressWarnings("unchecked") protected SessionFactory buildSessionFactory() { Configuration config = new Configuration(); DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString()); if (isExposeTransactionAwareSessionFactory()) { config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } if (this.hibernateProperties != null) { config.addProperties(this.hibernateProperties); } if (dataSource != null) { boolean actuallyTransactionAware = (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy); config.setProperty(Environment.CONNECTION_PROVIDER, actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class .getName() : LocalDataSourceConnectionProvider.class.getName()); } // 添加Entity的类 for (Class[] cArr : this.entityClasses.values()) { for (Class c : cArr) { config.addClass(c); } } this.configuration = config; return config.buildSessionFactory(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } /** * Return the Configuration object used to build the SessionFactory. Allows * access to configuration metadata stored there (rarely needed). * * @throws IllegalStateException * if the Configuration object has not been initialized yet */ public final Configuration getConfiguration() { if (this.configuration == null) { throw new IllegalStateException("Configuration not initialized yet"); } return this.configuration; } public void destroy() throws HibernateException { DataSource dataSource = getDataSource(); if (dataSource != null) { configTimeDataSourceHolder.set(dataSource); } try { super.destroy(); } finally { if (dataSource != null) { configTimeDataSourceHolder.set(null); } } } } 类LocalDataSourceConnectionProvider的代码: java 代码 package wanged.core.persistent; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.HibernateException; import org.hibernate.connection.ConnectionProvider; import org.hibernate.util.JDBCExceptionReporter; public class LocalDataSourceConnectionProvider implements ConnectionProvider { private DataSource dataSource; private DataSource dataSourceToUse; public void configure(Properties props) throws HibernateException { this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource(); if (this.dataSource == null) { throw new HibernateException("No local DataSource found for configuration - " + "dataSource property must be set on LocalSessionFactoryBean"); } this.dataSourceToUse = getDataSourceToUse(this.dataSource); } protected DataSource getDataSourceToUse(DataSource originalDataSource) { return originalDataSource; } public DataSource getDataSource() { return dataSource; } public Connection getConnection() throws SQLException { try { return this.dataSourceToUse.getConnection(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void closeConnection(Connection con) throws SQLException { try { con.close(); } catch (SQLException ex) { JDBCExceptionReporter.logExceptions(ex); throw ex; } } public void close() { } public boolean supportsAggressiveRelease() { return false; } }

相关推荐

Global site tag (gtag.js) - Google Analytics