【问题标题】:Issue with Autowiring + genericDAO pattern in spring春季自动装配 + genericDAO 模式的问题
【发布时间】:2013-10-22 16:01:36
【问题描述】:

在我的应用程序中,我使用的是通用 DAO 模式。我的班级结构如下所示:

  1. 一个领域类——pojo

    package com.test.abc.def;
    @NamedQueries({------a couple of queries go here .......})
    @Entity
    @Table(name = "NAME")
    public class Name implements Serializable {
       private String myName;
       ........
       @Column(name = "MY_NAME", nullable = false, length = 30)
       public String getMyName() {
          return this.myName;
       }
       public void setName(String myName) {
          this.myName= myName;
       }
           ........
    }
    
  2. 一个DAO接口,对应上面Domain类中的NamedQueries

    package com.test.abc.h;
    public interface INameDao extends IGenericDAO<...., ....> {
     ....method signature......
    }
    
  3. 一个 IGenericDAO 接口

    package com.test.abc.h;
    public interface IGenericDAO<T, PK extends Serializable> {
          .........
    }
    
  4. GenericDAO 实现类

    package com.test.abc.h.impl;
    @Repository
    @Scope( BeanDefinition.SCOPE_PROTOTYPE )
    public class GenericDAO<T, PK extends Serializable> implements IGenericDAO<T, PK> {
         ....method implemnetations ........
    }
    
  5. 应用上下文:

    <context:component-scan base-package="com.test.abc" />
    <context:annotation-config />
    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    
  6. 服务类具有以下自动装配声明:

     @Autowired
     private Name name;
     @Autowired
     private INameDAO nameDAO;
     ......
     nameDAO.callToNamedQuery() - here I would like to call the named query present in Name class.  
    

我在尝试启动服务器时看到以下错误:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No 
qualifying bean of type [com.test.abc.h.INameDAO] 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)}

我在这里缺少什么? 我尝试将 @Repository 注释添加到 INameDAO - 以及 Name 域类。那没有帮助。 还在 Name 域类中添加了 @Component 注释 - 这也没有帮助。

【问题讨论】:

    标签: spring annotations autowired hibernate-generic-dao


    【解决方案1】:

    您的 INameDao 是接口,并且 INameDao 没有实现任何类作为您的代码。@Autowired 用于依赖注入,@Autowires 未找到任何 INameDao 实现类。所以需要先创建一个INameDao的Impl类。您的例外是 NoSuchBeanDefinitionException,因此 spring 没有找到任何类型为 [com.test.abc.h.INameDAO] 的合格 bean。

    【讨论】:

      【解决方案2】:

      看起来您的GenericDAOIGenericDAO 类型,但您的错误提示您正在注入INameDAO 类型的bean。虽然INameDAO 属于IGenericDAO 类型,但您的GenericDAO 不是INameDAO 类型。您需要修复 GenericDAO 的继承树,或者更改要注入的 bean 的类型以在其树中包含某些内容。

      编辑

      举个例子。这类似于定义 java.util.Collection、java.util.List 和 java.util.Set。然后,您声明一个具有 List 属性的 bean 并尝试注入一个 Set。虽然他们有共同的祖先,但他们是不相容的。您可以更改您的 bean 以接受 Collection 属性,但您将被限制为 Collection 的方法。

      使用下面的结构,您可以将MyActualDAOImpl 注入MyActualDAO 类型的属性中(我已经省略了泛型)。把你的NamedQueries on yourEntity`。

      公共接口:

      public interface GenericDAO{
          //crud methods
      }
      
      public interface MyActualDao inherits GenericDAO{
          //other non-crud methods, if needed
      }
      

      实施

      public abstract class AbstractDAO implements GenericDAO{
          //generic implementations of CRUD
      }
      
      
      public MyActualDAOImpl inherits AbstractDAO implements MyActualDAO{
          ...
      }
      

      【讨论】:

      • 我自动装配 INameDAO 的原因是能够调用名称域类中存在的命名查询。编辑了我的问题以包含此信息。
      • 那么你需要重构你的代码,因为 Spring 会尝试按类型注入,而你的 GenericDAO 不是 INameDAO 类型。使用您当前的定义,您可以使您的目标 bean 成为通用类型 IGenericDAO,但我希望您将失去对 GenericDAO 中其他方法的可见性。无论哪种方式,您当前的结构都行不通。
      • 对我需要做出的具体更改有什么建议吗?
      • 更新回复以获得额外空间。
      • 感谢您提供上述示例,但我看到您在这里为 DAO 添加了一个 Impl。这意味着再添加一个类并将 NamedQueries 作为方法移动到该 Impl 中。有没有办法避免这种情况?
      猜你喜欢
      • 1970-01-01
      • 2019-08-02
      • 2017-12-13
      • 2015-12-11
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多