Spring Annotations -java.lang.IllegalArgumentException:spring + hibernate中需要'sessionFactory'或'hibernateTemplate'

时间:2013-09-17 12:38:02

标签: java spring hibernate spring-mvc sessionfactory

我收到了问题中的错误。我的Dao实施班如下:

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文件。

2 个答案:

答案 0 :(得分:4)

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

  1. 当它真正需要一个Hibernate FactoryBean<SessionFactory>时,你正在注入一个Spring SessionFactory
  2. 实际上并没有使用注入的依赖项。
  3. 您尝试使用HibernateDaoSupport#getHibernateTemplate()而没有提及SessionFactoryHibernateTemplate
  4. 请注意,只要您为HibernateDaoSupport提供HibernateTemplateSessionFactory就会创建自己的AnnotationSessionFactoryBean sessionFactory

    我建议你做出以下改动:

    1. UserDaoImpl
    2. 删除 UserDaoImpl 利用其继承的setSessionFactory(SessionFactory)方法
    3. 修复 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); } } 的配置

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

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

      这个配置代码:

      FactoryBean

      请注意,可以从sessionFactory()配置方法返回InitializingBean,因为Spring会检测并利用其生命周期方法(通过DisposableBeanFactoryBean),但是你需要通过自己调用getObject()方法{{1}}来适应。

答案 1 :(得分:3)

不要使用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作为您的存储库。为您节省了大量的实现代码。 (最好的可维护和可测试的代码是代码没有写:))。