java - 在带有 Hibernate 的 JAR 中使用 Spring 的困难

标签 java hibernate jar

我正在尝试从现有应用程序中分离出 Hibernate DAO 和模型对象层,以便它们可以跨多个应用程序使用。不幸的是,我没有取得太大成功:尝试从应用程序上下文获取 SessionFactory 时抛出 NoSuchBeanDefinitionException。

所有 DAO 类都扩展名为 GenericDaoHibernate2 的类。每个 DAO 都扩展了它,并在构造函数中传递一个类。相当标准的通用 DAO 东西。

我认为这也是设置 session 工厂的合理位置(有很多 DAO 类)。因此,在构造函数类中,我这样做了:

public GenericDaoHibernate2(final Class<T> persistentClass) {
    ctx = new ClassPathXmlApplicationContext("META-INF/applicationContext-dao.xml");
    this.sessionFactory = (SessionFactory) ctx.getBean(SessionFactory.class);
    log.debug("Value of app context: " + ctx.toString());
    log.debug("Value of sessionFactory: " + sessionFactory);
    this.persistentClass = persistentClass;
}

不幸的是,这因前面提到的异常而失败了:

Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
Truncated. see log file for complete stacktrace

我还尝试使用类路径中的应用程序上下文文件进行此操作,在声明变量等时设置值,等等。

猜测发生的事情是,作为 Maven 构建的一部分,jar 没有引用类路径上的库,但我真的不知道......

更新:愚蠢,愚蠢的我...忘记显示应用程序上下文文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/jee
       http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"
    default-lazy-init="true">

    <tx:annotation-driven transaction-manager="transactionManager" />
    <context:component-scan base-package="org.jason.dao.hibernate" />


    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@//192.168.1.1/db01" />
        <property name="username" value="USER" />
        <property name="password" value="PASSWORD" />
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibername.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
                <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
                <prop key="hibernate.default_catalog">CATALOG</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
                </prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>org.jason.model</value>
            </list>
        </property>
    </bean>
</beans>

另一个更新:被要求提供示例 DAO。该接口(interface)是一个“标准”通用接口(interface),接受通用参数 T 和 PK,就像 Impl 一样。下面这个除了从 GenericDaoHibernate2 继承的方法之外没有任何特定的方法。

@Repository("AreaOfPreferenceDAO")
public class HibernateAreaOfPreferenceDAO extends GenericDaoHibernate2<AreaOfPreference, AreaOfPreferenceCompositeId> implements AreaOfPreferenceDAO {

   public HibernateAreaOfPreferenceDAO()
   {
      super(AreaOfPreference.class);
   }
}

最佳答案

为了将 SessionFactory 连接到您的自定义通用 DAO 中,您可以继续并简单地使用 @Autowire,只要整个 Spring 上下文正在定义 SessionFactory bean。 定义 bean:

<bean id="sessionFactory" class=
    "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="packagesToScan" value="org.rest" />

   <property name="hibernateProperties">
      ...
   </property>
</bean>
<bean id="dataSource" class=
    "org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="${driverClassName}" />
   <property name="url" value="${url}" />
   <property name="username" value="restUser" />
   <property name="password" value="restmy5ql" />
</bean>

连接起来很简单:

@Autowired
SessionFactory sessionFactory;

引导上下文的正确位置不在 DAO 的构造函数中;如果您正在使用 Web 应用程序,则可以使用传统方法:

<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>/</url-pattern>
 </servlet-mapping>

由于这不是一个 Web 应用程序,因此无法在 web.xml 中引导上下文;但是,引导仍然需要在外部 - 主类只需要创建 XmlWebApplicationContext 并配置它。

希望这有帮助。

关于java - 在带有 Hibernate 的 JAR 中使用 Spring 的困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12037610/

相关文章:

java - SIGSTOP 和 SIGTSTP 会损坏 JVM 吗?

java - 在.jar上运行音频文件

java - 检查 jar 是否正在运行

java - 在线程 "main"java.lang.StackOverflowError 中获取异常

java - 具有 sftp 图像的测试容器在 "nc not found"或 "Address Not Available"上抛出错误

java - String indexOf 方法不适用于字符串中的第一个字符

java - OSGi 上的 PostgreSQL 连接器

java - 面临无法延迟初始化集合并且无法初始化代理 - 无 session

postgresql - 如何清理 Spring Boot 应用程序中的数据库表?

java - 读取 jar 文件中的数据(Java 中)并对文件进行计数