【问题标题】:Spring Annotations -java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required in spring+hibernateSpring Annotations -java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required in spring+hibernate
【发布时间】:2013-09-17 12:38:02
【问题描述】:

我收到问题中的错误。我的道实现类如下:

package com.argus.intenew;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

@Autowired
AnnotationSessionFactoryBean sessionFactory;
    public UserDaoImpl() {
    }

    public AnnotationSessionFactoryBean getCurrentSessionFactory() {
        return sessionFactory;
    }

    public void  setCurrentSessionFactory(AnnotationSessionFactoryBean sessionfactory) {
        this.sessionFactory = sessionfactory;
    }

    @Override
    public void addUser(UserMap userMap) {
        System.out.println("33333333333333333333");
        getHibernateTemplate().save(userMap);
    }

    @Override
    public List<User> findAllUser() {
        return getHibernateTemplate().find("from User");
    }

    @Override
    public void deleteUser(UserMap user) {
        getHibernateTemplate().delete(user);
    }

    @Override
    public void updateUser(UserMap user) {
        getHibernateTemplate().update(user);
    }
}

而我的配置类如下:

package com.argus.intenew;

import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

@Configuration
@ComponentScan(basePackages = {"com.argus.intenew"})
public class Webconfig  {
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "org.hibernate.dialect.MySQLDialect ";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "true";

    @Bean
    public DataSource dataSource() {
        System.out.println("----------InDATAsource------------");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/MyUser");
        dataSource.setUsername("root");
        dataSource.setPassword("XXX");
        System.out.println("----------OutofDATAsource------------");
        return dataSource;
    }

    @Bean
    public AnnotationSessionFactoryBean sessionFactory() {
        System.out.println("----------InsessionFactory------------");
        AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        String[] pckage={"com.argus.intenew"};
        sessionFactory.setPackagesToScan(pckage);
        sessionFactory.setHibernateProperties(hibProperties());
        System.out.println("----------Outof session------------");
        return sessionFactory;
    }

    private Properties hibProperties() {
        System.out.println("----------InhipProp------------");
        Properties properties = new Properties();
        properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, "org.hibernate.dialect.MySQLDialect ");
        properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, "true");
        System.out.println("----------outofhip------------");
        return properties;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory().getObject());

        return transactionManager;
   }

   @Bean
   public UserBoImpl userBo() {
       System.out.println("----------InUserBo------------");
       UserBoImpl userBo= new UserBoImpl();
       userBo.setUserDao(userDao());
       System.out.println("----------OutofUserbo------------");
       return userBo;
   }

   @Bean
   public UserDaoImpl userDao() {
       System.out.println("----------InUserDao------------");
       UserDaoImpl userDao=new UserDaoImpl();
       userDao.setCurrentSessionFactory(sessionFactory());
       System.out.println("----------OutofUserDao------------");
       return userDao;
   }
}

请任何人帮助并告诉我使用注释执行此操作的正确方法是什么。 这里我没有使用任何 xml 文件。

【问题讨论】:

  • 如果你要扩展HibernateDaoSupport,你需要给超类一个引用你注入的SessionFactory,然后才能使用getHibernateTemplate()

标签: java spring hibernate spring-mvc sessionfactory


【解决方案1】:

您的 DAO 实现未正确利用其超类。

  1. 当它确实需要休眠 SessionFactory 时,您正在注入 Spring FactoryBean&lt;SessionFactory&gt;
  2. 实际上并没有使用注入的依赖项。
  3. 您正在尝试使用 HibernateDaoSupport#getHibernateTemplate() 而不给它提供对 SessionFactoryHibernateTemplate 的引用。

注意HibernateDaoSupport 将创建自己的HibernateTemplate,只要你给它一个SessionFactory

我建议您进行以下更改:

  1. 删除 AnnotationSessionFactoryBean sessionFactoryUserDaoImpl
  2. 修复 UserDaoImpl 的配置,利用其继承的 setSessionFactory(SessionFactory) 方法

所以你实际上最终得到了这个 DAO 代码:

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
    @Override
    public void addUser(UserMap userMap) {
        getHibernateTemplate().save(userMap);
    }
    @Override
    public List<User> findAllUser() {
        return getHibernateTemplate().find("from User");
    }
    @Override
    public void deleteUser(UserMap user) {
        getHibernateTemplate().delete(user);
    }
    @Override
    public void updateUser(UserMap user) {
        getHibernateTemplate().update(user);
    }
}

还有这个配置代码:

@Configuration
@ComponentScan(basePackages = {"com.argus.intenew"})  
public class Webconfig  {
    //snip...
    @Bean
    public UserDaoImpl userDao() {
        UserDaoImpl userDao=new UserDaoImpl();
        userDao.setSessionFactory(sessionFactory().getObject());
        return userDao;
    }
}

请注意,可以从 sessionFactory() 配置方法返回 FactoryBean,因为 Spring 将检测并利用其生命周期方法(通过 InitializingBeanDisposableBean),但您需要通过调用 @987654339 来适应@方法getObject()你自己。

【讨论】:

    【解决方案2】:

    不要使用 HibernateDaoSupport 和/或 HibernateTemplate。随着 Hibernate 3.0.1 的发布,该支持应被视为已弃用。正如the reference guide 中提到的,基于普通的hibernate 实现dao/repository。

    你的 dao 看起来像

    @Repository
    public class UserDaoImpl implements UserDao {
    
        @Autowired
        private SessionFactory sessionFactory;
    
        @Override
        public void addUser(UserMap userMap) {
            System.out.println("33333333333333333333");
            sessionFactory.getCurrentSession().save(userMap);
        }
    
        @Override
        public List<User> findAllUser() {
            return sessionFactory.getCurrentSession().createQuery("from User").list();
        }
    
        @Override
        public void deleteUser(UserMap user) {
            sessionFactory.getCurrentSession().delete(user);
        }
    
        @Override
        public void updateUser(UserMap user) {
            sessionFactory.getCurrentSession().update(user);
        }
    }
    

    由于您已经在使用 @ComponentScan 注释(并且我假设您的 BO 已使用 @Service 注释并正确使用 @Autowired 注释,因此无需在配置中明确配置您的 dao 和服务。

    @Configuration  
    @ComponentScan(basePackages = {"com.argus.intenew"})  
    public class Webconfig  {  
    
        private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "org.hibernate.dialect.MySQLDialect ";  
        private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "true";  
    
        @Bean  
        public DataSource dataSource() {  
            DriverManagerDataSource dataSource = new DriverManagerDataSource();  
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");  
            dataSource.setUrl("jdbc:mysql://localhost:3306/MyUser");  
            dataSource.setUsername("root");  
            dataSource.setPassword("XXX");  
            return dataSource;  
        }  
    
        @Bean  
        public AnnotationSessionFactoryBean sessionFactory() { 
            AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();  
            sessionFactory.setDataSource(dataSource());
            String[] pckage={"com.argus.intenew"};
            sessionFactory.setPackagesToScan(pckage);  
            sessionFactory.setHibernateProperties(hibProperties());
            return sessionFactory; 
        }  
    
        private Properties hibProperties() { 
            Properties properties = new Properties();  
            properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, "org.hibernate.dialect.MySQLDialect ");  
            properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, "true"); 
            return properties;    
        } 
    
        @Bean  
        public HibernateTransactionManager transactionManager() {  
            return new HibernateTransactionManager(sessionFactory().getObject());  
        }  
    }
    

    关于DriverManagerDataSource 的注释很适合测试,但请不要在生产中使用它(除非您想要一个无法执行的应用程序)。请改用适当的 JDBC 连接池。

    最后一点,如果您真的希望生产力下降休眠,请切换到 JPA 并使用 Spring Data JPA 作为您的存储库。节省您编写大量的实现代码。 (最好的可维护和可测试的代码是未编写的代码:))。

    【讨论】:

      猜你喜欢
      • 2018-09-12
      • 2019-04-26
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 2012-06-10
      • 2015-12-31
      相关资源
      最近更新 更多