我们在项目和他们自己的实现中有很多DAO。例如,我有一个名为CorDAO和CorDAOHibernate的类(CorDAO是一个接口,CorDAOHibernate实现了CorDAO)。对于我需要的每个接口:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.myproject.*.to"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<bean id="genericDAO" class="com.myproject.dao.hibernate.GenericDAOHibernate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="CorDAO" class="com.myproject.dao.hibernate.CorDAOHibernate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="ExampleDAO" class="com.myproject.dao.hibernate.ExampleDAOHibernate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
这就是我想在com.myproject.dao.hibernate。*包中使用ComponentScan的原因。请注意,CorDAO是 @Repository ,而CorDAOHibernate没有任何注释。 每个DAO课程都是GenericDAO的孩子。
如何使用ComponentScan?我使用的是Spring 3,所以我尝试了这个:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.myproject.*.to"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<context:component-scan base-package="com.myproject.dao.hibernate" />
我在CorDAOHibernate和GenericDAOHibernate中添加了一个 @Component 注释但是我得到了一个IllegalArgumentException:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'corDAOHibernate' defined in URL [jar:file:/home/danielamorais/Documents/apache-tomcat-8.0.47/webapps/myproject/WEB-INF/lib/myproject-3.1.0.jar!/com/myproject/dao/hibernate/corDAOHibernate.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
我认为这是因为sessionFactory在GenericDAOHibernate中自动装配但在CorDAOHibernate中为null。如何使用组件扫描解决此问题?
类 CorDAO
@Repository
public interface CorDAO extends GenericDAO {
//Methods
}
CorDAOHibernate
@Component
public class CorDAOHibernate extends GenericDAOHibernate implements CorDAO {
//Methods
}
GenericDAO
public interface GenericDAO extends DAO {
//Methods. This class doesn't contains @Repository annotation
}
GenericDAOHibernate
@Component
public class GenericDAOHibernate extends HibernateDaoSupport implements GenericDAO, PropertySelector {
@Autowired
private SessionFactory sessionFactory;
protected Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
//Methods
}
DAO
public interface DAO {
//There's no method here.
}
另外,添加 @Component(&#34; genericDAO&#34;)我得到了(可能是因为继承问题):
NoUniqueBeanDefinitionException: No qualifying bean of type [com.myproject.dao.GenericDAO] is defined: expected single matching bean but found 88
答案 0 :(得分:1)
嗯,您的主要问题是因为:
调用init方法失败;嵌套异常是java.lang.IllegalArgumentException:必需'sessionFactory'或'hibernateTemplate'
我也回答了类似的问题before。
长话短说,GenericDAOHibernate
的实现方式错误:
SessionFactory
那样在内部实现HibernateDaoSupport
,而只需致电getSessionFactory()
即可SessionFactory
传递给HibernateDaoSupport
,以便在HibernateTemplate
中初始化HibernateDaoSupport
。否则,它将为null,因此会发生此异常消息。此外,您的@Repository
和@Component
似乎也被注释了。基本上,我只会对DAO使用@Repository
。它与@Component
相同,并带有spring“ exception translation”功能。
无论如何,请尝试更改为以下内容:
@Repository
public class GenericDAOHibernate extends HibernateDaoSupport implements GenericDAO, PropertySelector {
@Autowired
public GenericDAOHibernate(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
protected Session getCurrentSession() {
return getSessionFactory().getCurrentSession();
}
}
每个DAO实现:
@Repository
public class CorDAOHibernate extends GenericDAOHibernate implements CorDAO {
public CorDAOHibernate(SessionFactory sessionFactory) {
super(sessionFactory);
}
}
还要从@Repository
界面中删除CorDAO
和@Component("genericDAO")
的内容.....
答案 1 :(得分:0)
您必须将声明为sessionFactory
的类注释为@Bean(或@Component,请参阅this question并确保它将通过ComponentScan进行扫描。
另外,请考虑使用Spring Data中的Repository方法,以便您不必编写样板代码。
答案 2 :(得分:0)
我认为您应该删除
@自动连线 私有SessionFactory sessionFactory;
字段。
因为sessionFactory字段已经在父类中定义。并将setSessionFactory方法清除为final。因此,您无需为sessionFactory清除新的私有字段。
这是setSessionFactory方法的实现。
/**
* Set the Hibernate SessionFactory to be used by this DAO.
* Will automatically create a HibernateTemplate for the given SessionFactory.
* @see #createHibernateTemplate
* @see #setHibernateTemplate
*/
public final void setSessionFactory(SessionFactory sessionFactory) {
if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
this.hibernateTemplate = createHibernateTemplate(sessionFactory);
}
}
同时删除sessionFactory和getCurrentSession(HibernateDaoSupport已经具有currentSession()方法)
或如下更改getCurrentSession
public class GenericDAOHibernate extends HibernateDaoSupport implements GenericDAO, PropertySelector {
protected Session getCurrentSession() throws DataAccessResourceFailureException {
return currentSession()
}
//Methods
}