2016-10-04 49 views
1

使用Spring和hibernate使用Java配置創建應用程序。儘管爲這個錯誤提供瞭解決方案,但我無法理解@Configuration和HibernateException之間的關係。在我的代碼中,我在服務上使用了@EnableTransactionManager和@Transaction。未使用@Configuration時,無法獲取當前線程錯誤的事務同步會話。在什麼情況下@Configuration是必需的?

下面是代碼:

AppInitializer.java

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class[]{HibernateConfiguration.class}; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[]{SpringConfiguration.class}; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[]{"/"}; 
    } 

} 

SpringConfiguration.java

@ComponentScan(basePackages = "com.o2o.project") 
public class SpringConfiguration { 

    @Bean(name="jspViewResolver") 
    public InternalResourceViewResolver getViewResolvers(){ 

     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setViewClass(JstlView.class); 
     viewResolver.setPrefix("WEB-INF/view/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 


} 

HibernateConfiguration.java

@EnableTransactionManagement 
    @PropertySource(value={"classpath:database.properties"}) 
    public class HibernateConfiguration { 

     @Autowired 
     private Environment environment; 

     @Bean(name="sessionFactory") 
     public LocalSessionFactoryBean sessionFactory() { 
      LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
      sessionFactory.setDataSource(dataSource()); 
      sessionFactory.setPackagesToScan(new String[] { "com.o2o.project.model" }); 
      sessionFactory.setHibernateProperties(hibernateProperties()); 
      return sessionFactory; 
     } 

     @Bean(name="dataSource") 
     public DataSource dataSource(){ 
      DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
      dataSource.setDriverClassName(environment.getProperty("database.driver")); 
      dataSource.setUrl(environment.getRequiredProperty("database.url")); 
      dataSource.setUsername(environment.getRequiredProperty("database.user")); 
      dataSource.setPassword(environment.getRequiredProperty("database.password")); 
      return dataSource; 
     } 

     private Properties hibernateProperties(){ 
      Properties properties = new Properties(); 
      properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")); 
      properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
      properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto")); 
      return properties;   
     } 

     @Bean(name="transactionManager") 
     public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { 
      HibernateTransactionManager transactionManager = new HibernateTransactionManager(); 
      transactionManager.setSessionFactory(sessionFactory); 
      return transactionManager; 
     } 

    } 

EmployeeServiceImpl.jav一個

@Service("employeeService") 
@Transactional 
public class EmployeeServiceImp implements EmployeeService { 

    @Autowired 
    private EmployeeDAO employeeDAD; 

    @Override 
    public void addEmployee(EmployeeModel employeeModel) { 
     employeeDAD.addEmployee(employeeModel); 
    } 

    @Override 
    public List<EmployeeModel> list() { 
     return employeeDAD.list(); 
    } 

    @Override 
    public EmployeeModel searchEmployee(int employeeID) { 
     return employeeDAD.searchEmployee(employeeID); 
    } 

} 

案例1 如果我註釋類HibernateConfiguration與「@配置/ @組件」,那麼它是工作沒有拋出任何異常,否則我得到HibernateException的:無法獲得交易同步會話當前線程。

案例2 即使嘗試添加在SpringConfiguration如下面HibernateConfiguration類中定義的豆類,代碼工作正常不與@Configuration註釋SpringConfiguration:

@ComponentScan(basePackages = "com.o2o.project") 
@EnableTransactionManagement 
@PropertySource(value={"classpath:database.properties"}) 
public class SpringConfiguration { 

    @Bean(name="jspViewResolver") 
    public InternalResourceViewResolver getViewResolvers(){ 

     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setViewClass(JstlView.class); 
     viewResolver.setPrefix("WEB-INF/view/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 

    @Autowired 
    private Environment environment; 

    @Bean(name="sessionFactory") 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
     sessionFactory.setDataSource(dataSource()); 
     sessionFactory.setPackagesToScan(new String[] { "com.o2o.project.model" }); 
     sessionFactory.setHibernateProperties(hibernateProperties()); 
     return sessionFactory; 
    } 

    @Bean(name="dataSource") 
    public DataSource dataSource(){ 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName(environment.getProperty("database.driver")); 
     dataSource.setUrl(environment.getRequiredProperty("database.url")); 
     dataSource.setUsername(environment.getRequiredProperty("database.user")); 
     dataSource.setPassword(environment.getRequiredProperty("database.password")); 
     return dataSource; 
    } 

    private Properties hibernateProperties(){ 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")); 
     properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
     properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto")); 
     return properties;   
    } 

    @Bean(name="transactionManager") 
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { 
     HibernateTransactionManager transactionManager = new HibernateTransactionManager(); 
     transactionManager.setSessionFactory(sessionFactory); 
     return transactionManager; 
    } 

} 

即使我沒有註釋SpringConfiguration.class在使用@Configuration的AppInitializer的getServletConfigClasses()中提到,它工作正常。在我遇到的大多數文檔中,有人提到@Configuration在定義類中的@Bean多於@Bean時使用,但在沒有使用@Configuration註釋的情況2下它工作正常。

爲什麼我在刪除@ Configuration/@ Component時收到上述異常。什麼時候應該使用@Configuration?我真的很困惑,當@Configuration是必需的?

回答

0

由於您沒有使用彈簧配置XML文件,並在下面的配置標籤

<beans> 
     <context:annotation-config/> 
     <bean class="yourpackge.HibernateConfiguration"/> 
    </beans> 

所以,你必須使用@Configuration,那麼只有你@Bean@Autowired註解的方法會得到bean定義和服務請求在運行時你的申請。

在你有getServletConfigClasses()有那麼它不需要與@Configuration

到annotanate因此,它顯然意味着對於任何Bean定義這需要有@Configuration@Component annotanation

你沒有任何 @Bean@Autowired annotanation其他案例

我認爲它澄清了你的疑問。

+0

即使嘗試了另一種方式,通過添加SpringConfiguration中HibernateConfiguration類中定義的bean並刪除了HibernateConfiguration。java文件 - (請參閱案例2)。仍然不需要使用@Configuration註釋SpringConfiguration。 –

+0

是的,但在**情況2 **中,您已在** SpringConfiguration **類中使用_ @ ComponentScan_進行了註釋,它將自己配置爲配置類,因此您不一定需要提及_ @ Configuration_。如果你刪除了_ @ ComponentScan_,那麼你將會遇到異常。 – Tanveer

相關問題