【问题标题】:why my controller not wired with my repository为什么我的控制器没有连接到我的存储库
【发布时间】:2019-12-10 07:37:51
【问题描述】:
package jerceka.workhard.demo;
@SpringBootApplication
@ComponentScan("jerceka.workhard.demo")
@EntityScan("jerceka.workhard.demo.Account")
@EnableJpaRepositories("jerceka.workhard.demo.Repo")
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}
package jerceka.workhard.demo;
@Entity
public class Account {
    @Id
    @GeneratedValue
    private int Id;
    private String Name;
    private int Age;
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getAge() {
        return Age;
    }
    public void setAge(int age) {
        Age = age;
    }
    @Override
    public String toString() {
        return "Account [Name=" + Name + ", Age=" + Age + "]";
    }
}
package jerceka.workhard.demo;
@Repository
public interface Repo extends CrudRepository<Account, Long>{
    @Query("select * from Account where Name=?1")
    List<Account> findByName(String name);
}
package jerceka.workhard.demo;
@Controller
public class Main{
    @Autowired
    Repo repo;
    @RequestMapping
    public String Home() {
        return "Home.jsp";
    }
    @RequestMapping("Create")
    public String Create(Account a) {
        repo.save(a);
        return "Home.jsp";
    }
    @RequestMapping("Bring")
    public ModelAndView Bring(@RequestParam int Id) {
        ModelAndView MV = new ModelAndView("Show.jsp");
//      Account a = repo.findById(Id).orElse(new Account());
//      System.out.println(repo.findByName("Mn"));
//      MV.addObject(a);
        return MV;
    }
}

把那个错误告诉我


应用程序启动失败


说明:

jerceka.workhard.demo.Main 中的字段 repo 需要一个无法找到的“jerceka.workhard.demo.Repo”类型的 bean。

注入点有以下注解: - @org.springframework.beans.factory.annotation.Autowired(required=true)

行动:

考虑在您的配置中定义一个“jerceka.workhard.demo.Repo”类型的 bean。

【问题讨论】:

  • 删除 @ComponentScan@EntityScan@EnableJpaRepositories@SpringBootApplication 会检测到这一点。
  • 没用,给我一个奇怪的错误 *
  • 请添加错误。 @SpringBootApplication 注释就足够了,因为它位于顶层的类中,其他所有内容(实体、存储库等都将被自动检测)。 @Query 也不需要,因为这是从 findByName 推断出来的。 @Repository 在 Spring Data 存储库中不需要。
  • 我满足你的所有要求,现在给我这个错误(创建名称为'main'的bean时出错:通过字段'repo'表示不满足的依赖关系;嵌套异常是org.springframework.beans.factory。 BeanCreationException:创建名为“repo”的bean时出错:调用init方法失败;嵌套异常是java.lang.IllegalArgumentException:无法为方法public abstract java.util.List jerceka.workhard.demo.Repo.findByName(java)创建查询.lang.String)!无法在此 ManagedType [jerceka.workhard.demo.Account] 上找到具有给定名称 [name] 的属性)我使用 mysql db btw
  • 您的字段名为Name,其中应为name。因此查询创建失败,您的 repo 无法找到并因此连接。修复您的实体,简而言之,使用正确的 Java 语法。

标签: java spring spring-boot


【解决方案1】:

您应该使用该框架,但是您正在非常努力地使用所有注释来解决该框架。接下来,您对实体中字段的命名约定不符合预期,因此事情开始出现问题。

  1. TestApplication 中删除所有注释,@SpringBootApplication 除外
  2. Repo 中删除@Repository@Query,您的密钥也是Integer 而不是Long
  3. 在您的实体中遵循正确的命名约定并使用小写字段而不是大写,因此nameage 而不是NameAge

你的TestApplication应该是这样的

package jerceka.workhard.demo;

@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

所有其他的东西都会自动启用。

您的Repo 应该定义如下,(我也将方法重命名为findAllByName,只是因为我认为它更匹配)。

package jerceka.workhard.demo;

public interface Repo extends CrudRepository<Account, Integer>{

    List<Account> findAllByName(String name);
}

最后,您的实体应遵循正确的命名约定。

package jerceka.workhard.demo;

@Entity
public class Account {
    @Id
    @GeneratedValue
    private int id;
    private String name;
    private int age;

    public int getId() {
        return this.id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Account [Name=" + this.anme + ", Age=" + this.age + "]";
    }
}

【讨论】:

    【解决方案2】:

    1) SpringBootApplication 是一个自给自足的注解

    您实际上并不需要您的类TestApplication 中的所有注释。 只需保持@SpringBootApplication 如下所示:

    package jerceka.workhard.demo;
    
    @SpringBootApplication
    public class TestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(TestApplication.class, args);
        }
    
    }
    

    2) 尊重属性的命名约定

    在您的类 Account 中,您的属性以大写字母开头。您应该尊重这个简单的命名约定。不知道你的代码的人会更容易阅读:

    • 以小写字母开头
    • 使用大写字母分隔属性中的单词(例如:myAttribute)

    3) 删除存储库中的 @Query

    您实际上并不需要此注释,因为下面的方法遵循查询方法命名约定,因此您的请求将完全相同。你可以找到更多关于这个 macanism here。 您的存储库应如下所示:

    package jerceka.workhard.demo;
    
    @Repository
    public interface Repo extends CrudRepository<Account, Long>{
    
        List<Account> findByName(String name);
    }
    

    4) 你不应该直接在你的控制器中注入你的存储库

    存储库应仅用于与数据库通信。它不应该直接注入控制器中。如果你想要一个干净的代码(在我看来),你应该创建一个服务(用 @Service 注释),并在这个类中编写你的所有逻辑。 Service 类是应用程序的核心。

    5) 使用@GetMapping、@PostMapping 等...代替@RequestMapping

    请求映射是“基础”注解,并不禁止使用它。但是由于有最新的注释,你应该使用它们。 @GetMapping@RequestMapping(method = RequestMethod.GET) 完全相同,但更具可读性。

    6) 尊重映射 url 的 REST 命名约定

    您应该按照以下简单规则编写路径:

    • 路径以“/”开始

    • 只使用小写

    • 用“-”分隔单词

      在您的情况下,您的 URL 应如下所示: "/create", "/bring"


      我希望这会对您有所帮助,并且您的代码可以正常工作。您仍然可以在评论部分向我提问。

    【讨论】:

    • 非常感谢您提供的所有说明,您的回答对我很有帮助
    【解决方案3】:

    将 Repo 代码更改为:

    package jerceka.workhard.demo;
    @Repository
    public interface Repo extends CrudRepository<Account, Integer>{
        @Query("select * from Account where Name=?1")
        List<Account> findByName(String name);
    }
    

    id 的数据类型在 entity 中是 int 但你在存储库中使用的是 Long。

    【讨论】:

    • 谢谢你的回答,我现在试了,还是不行,同样的问题
    【解决方案4】:

    在你的班级上方更改这一行TestApplication

    @EnableJpaRepositories("jerceka.workhard.demo.Repo")
    

    应该是这样的:

    @EnableJpaRepositories("jerceka.workhard.demo")
    

    注解采用包名,而不是类或接口的名称。

    【讨论】:

    • 感谢您的宝贵时间,但这又给了我一个错误Error creating bean with name 'repo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class jerceka.workhard.demo.Account
    • @Jerceka 那是因为你在这一行犯了同样的错误:@EntityScan("jerceka.workhard.demo.Account") 应该是@EntityScan("jerceka.workhard.demo")
    • 这是我的主要课程SpringBootApplication @ComponentScan("jerceka.workhard.demo") @EntityScan("jerceka.workhard.demo") @EnableJpaRepositories("jerceka.workhard.demo") public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } } 不工作并给我*错误
    【解决方案5】:

    删除Repo类名或替换以下代码

        @EnableJpaRepositories("jerceka.workhard.demo")
    

    【讨论】:

    • 感谢您的宝贵时间,但这又给了我一个错误Error creating bean with name 'repo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class jerceka.workhard.demo.Account
    【解决方案6】:

    @EntityScan@EnableJpaRepositories 采用 basePackages 数组进行扫描。

    所以不是

    @EntityScan("jerceka.workhard.demo.Account")
    @EnableJpaRepositories("jerceka.workhard.demo.Repo")
    

    用途:

    @EntityScan("jerceka.workhard.demo")
    @EnableJpaRepositories("jerceka.workhard.demo")
    

    注意:但是由于您已经在包"jerceka.workhard.demo" 的根级别中拥有@SpringBootApplication,所以您只需要@SpringBootApplication

    【讨论】:

      【解决方案7】:

      TestApplication 中你应该只保留SpringBootApplication

      @SpringBootApplication
      public class TestApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(TestApplication.class, args);
          }
      
      }
      

      并更改Repo中的选择

      @Repository
      public interface Repo extends CrudRepository<Account, Long> {
          @Query("select a from Account a where a.name=?1")
          List<Account> findByName(String name);
      }
      

      Account中将您的ID更改为Long

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多