简体   繁体   English

Spring通用Hibernate DAO

[英]Spring generic Hibernate DAO

I am writing a Generic Hibernate DAO class that all Hibernate DAO classes will inherit from. 我正在编写一个所有Hibernate DAO类都将继承的Generic Hibernate DAO类。 I am trying to use spring to inject the dependencies for the classes but I am getting an exception. 我试图使用spring注入类的依赖项,但我得到一个例外。

@Repository
public class HibernateDaoImpl <T>  implements Dao<T>{
    @Autowired
    private SessionFactory sessionFactory;
    @Autowired
    private Class<T> clazz;

     //setter & getter

    public HibernateDaoImpl (Class<T> clazz)
    {
      this.clazz = clazz;
    }
    public Session getCurrentSession ()
    {
        return sessionFactory.getCurrentSession();
    }

    public void save(T t) 
    {
        getCurrentSession().save(t);
    }

    public void update(T t) 
    {
        getCurrentSession().update(t);
    }


    @SuppressWarnings("unchecked")
    public T findById(Object object)
    {
        return (T) getCurrentSession().get(clazz, (Serializable)object);
    }

    @SuppressWarnings("unchecked")
    public List<T> findAll(int page, int maxResult) 
    {
        return getCurrentSession().createQuery(String.format("FROM %s", clazz.getSimpleName())).list();
    }

My derived class 我的派生类

public class SubscriberHibernateDao extends HibernateDaoImpl<Subscriber> implements SubscriberDao {

    public SubscriberHibernateDao ()
    {
        super(Subscriber.class);
    }
}

My spring-xml 我的spring-xml

<bean id="subscriber" class="com.example.model.Subscriber" autowire="byName">
    <property name="email" value="mdennis10"></property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/kyro"/>
    <property name="username" value="root"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.kyrogaming.model"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<bean id="subcriberDao" class="com.example.dao.SubscriberHibernateDao">
 <property name="clazz" value="com.example.model.Subscriber"></property>
</bean>

When I run this I get the following stack trace: 当我运行这个时,我得到以下堆栈跟踪:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDaoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Class com.example.dao.HibernateDaoImpl.clazz; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.kyrogaming.test.BeanTest.test(BeanTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Class com.example.dao.HibernateDaoImpl.clazz; 引起:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private java.lang.Class com.example.dao.HibernateDaoImpl.clazz; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[java.lang.Class]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者。 Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) ... 36 more Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. 依赖注释:{org.springframework.beans.factory.annotation.Autowired(required = true)}在org.springframework的org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)。 beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)... 36更多引起:org.springframework.beans .factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[java.lang.Class]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者。 Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) ... 38 more 依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}在org.springframework.beans的org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)。 or.s.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement上的factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856)。 inject(AutowiredAnnotationBeanPostProcessor.java:486)......还有38个

How can I fix this. 我怎样才能解决这个问题。

@Autowired 
private Class<T> clazz;

This line in your code will never work because spring does not know what to Autowire. 代码中的这一行永远不会起作用,因为spring不知道Autowire是什么。 You can only autowire by type or working class, type preferably. 您只能按类型或工作类进行自动装配,最好输入。

You will need to wrap this Class in a wrapper object so you can do the Autowire by type then inject that type into the DAO. 您需要将此类包装在包装器对象中,以便您可以按类型执行Autowire,然后将该类型注入DAO。

Example

@Autowired
private Entity<T> entity;

You are already setting the field clazz via setter-injection (in your spring-xml ): 您已经通过setter-injection设置了字段clazz (在spring-xml ):

<property name="clazz" value="com.example.model.Subscriber"></property>

So there's no need for @Autowired on the field clazz . 所以在场上的clazz上不需要@Autowired However, you need to add a setter for field clazz , otherwise Spring won't be able to perform Setter-Injection. 但是,您需要为字段clazz添加setter,否则Spring将无法执行Setter-Injection。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM