java - 无法注册以 null 定义的 bean 'postRepository' 。具有该名称的 bean 已在 null 中定义

标签 java spring spring-boot spring-data-jpa

我正在 Spring Boot 中开发一个简单的博客后端作为个人项目。我这样做是为了尝试学习一些 Java Spring,但我在使用下面的代码时遇到了问题(有很多......)。

我得到的错误正是这样的:在 null 中定义的 bean 'postRepository' 无法注册。具有该名称的 bean 已在 null 中定义,并且覆盖已禁用。

当我使用 Hibernate 时,代码本身工作得很好,我有 2 个 DAO、2 个 DAOImpl,并使用服务类中的这些来调用数据库并返回。一切都按预期进行 - 可以返回完整的用户列表,可以返回完整的帖子列表,单个用户/帖子等。所有 CRUD 操作。

如果我理解正确的话,要切换到 Spring Data JPA,我所需要做的就是摆脱 DAODAOImplementations每个实体只有一个扩展 JpaRepository<T, T> 的接口(interface)它将提供 findById、findAll、save、delete 等的实现。但是,进行更改后,删除 DAODAOImplementations然后更新 ServiceImplementations,我收到上述错误。以下是实体类:

课后:

package com.me.website.entity;

@Entity
@Table(name="posts")
public class Post {
    //fields of the Post object
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private int id;
    @Column(name="title")
    private String title;
    @Column(name="author")
    private String author;
    @Column(name="date")
    private LocalDateTime date;
    @Column(name="excerpt")
    private String excerpt;
    @Column(name="featured_media")
    private byte[] featuredMedia;
    @Column(name="content")
    private String content;
    @Column(name="category")
    private String category;

    //constructor for the Post object
    public Post(String title, String author, LocalDateTime date, String excerpt, byte[] featuredMedia, String content, String category) {
        this.title = title;
        this.author = author;
        this.date = date;
        this.excerpt = excerpt;
        this.featuredMedia = featuredMedia;
        this.content = content;
        this.category = category;
    }

    public Post() {}

    @Override
    public String toString() {
        return "Post{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", author=" + author +
                ", date=" + date +
                ", excerpt='" + excerpt + '\'' +
                ", featuredMedia=" + Arrays.toString(featuredMedia) +
                ", content='" + content + '\'' +
                ", category='" + category + '\'' +
                '}';
    }

    //getters and setters

用户类别

package com.me.website.entity;

@Entity
@Table(name="users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;
    @Column(name="username")
    private String username;
    @Column(name="display_name")
    private String displayName;
    @Column(name="first_name")
    private String firstName;
    @Column(name="last_name")
    private String lastName;
    @Column(name="email")
    private String email;
    @Column(name="password")
    private String password;

    public User() {}

    public User(String username, String displayName, String firstName, String lastName, String email, String password) {
        this.username = username;
        this.displayName = displayName;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
    }


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", displayName='" + displayName + '\'' +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

//getters and setters

使用 Spring Data JPA 的 DAO

package com.me.website.dao;

public interface PostRepository extends JpaRepository<Post, Integer> {
    //no implementation required
}
package com.psyonik.website.dao;

public interface UserRepository extends JpaRepository<User, Integer> {
    //no implementation required
}

帖子/用户服务

package com.me.website.service;

public interface PostService {
    public List<Post> findAll();
    public Post findById(int theId);
    public void save(Post thePost);
    public void deleteById(int theId);
}

package com.me.website.service;

public interface UserService {
    public List<User> findAll();
    public User findById(int theId);
    public void save(User theUser);
    public void deleteById(int theId);
}

服务实现

package com.me.website.service;

@Service
public class PostServiceImpl implements PostService {
    private PostRepository postRepository;

    @Autowired
    public PostServiceImpl(PostRepository thePostRepository) {
        postRepository=thePostRepository;
    }

    @Override
    public List<Post> findAll() {
        return postRepository.findAll();
    }

    @Override
    public Post findById(int theId) {
        Post thePost = null;
        Optional<Post> byId = postRepository.findById(theId);
        if (byId.isPresent()) {
            thePost = byId.get();
        }
        return thePost;
    }

    @Override
    public void save(Post thePost) {
        postRepository.save(thePost);
    }

    @Override
    public void deleteById(int theId) {
        postRepository.deleteById(theId);
    }
}
package com.me.website.service;

@Service
public class UserServiceImpl implements UserService {
    private UserRepository userRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public List<User> findAll() {
        return userRepository.findAll();
    }

    @Override
    public User findById(int theId) {
        User theUser = null;
        Optional<User> thisUser = userRepository.findById(theId);
        if (thisUser.isPresent()) {
            theUser = thisUser.get();
        }
        return theUser;
    }

    @Override
    public void save(User theUser) {
        userRepository.save(theUser);
    }

    @Override
    public void deleteById(int theId) {
        userRepository.deleteById(theId);
    }
}

POST 休息 Controller

package com.me.website.restcontroller;

@RestController
@RequestMapping("/")
public class PostRESTController {
    private PostService postService;

    @Autowired
    public PostRESTController(PostService thePostService) {

        postService = thePostService;
    }


    /*GET mapping - this one returns a list of all the posts =========================================================*/
    @GetMapping("/blog")
    public List<Post> findAll() {
        return postService.findAll();
    }


    /*GET mapping - this provides a pathvariable for a postId to retrieve a particular post item or return an error ==*/
    @GetMapping("/blog/{postId}")
    public Post findById(@PathVariable int postId) {
        Post post = postService.findById(postId);
        if (post == null) {
            throw new RuntimeException("Post not found " + postId);
        }
        else return post;
    }


    /*POST mapping - this creates a new blogpost object and saving it to the db ======================================*/
    @PostMapping("/blog")
    public Post addPost(@RequestBody Post thePost) {
        //in case an id is passed, this will be converted to 0 to force an insert instead of an update
        thePost.setId(0);
        postService.save(thePost);
        return thePost;
    }


    /*PUT mapping - this updates a given blog post given the id passed through =======================================*/
    @PutMapping("/blog")
    public Post updatePost(@RequestBody Post thePost) {
        postService.savePost(thePost);
        return thePost;
    }


    /*DELETE mapping - this is to delete a specific blog post item ===================================================*/
    @DeleteMapping("/blog/{blogId}")
    public String deletePost(@PathVariable int blogId) {
        //retrieve the correct post
        Post thePost = postService.findById(blogId);
        //throw exception if null
        if (thePost == null) {
            throw new RuntimeException("This post doesn't exist in db. Post ID: " + blogId);
        }
        else {
            postService.deleteById(blogId);
        }
        return "Deleted post with id: " + blogId;
    }
}
package com.me.website;

@SpringBootApplication
public class WebsiteApplication {

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

}

我已经删除了导入语句,因为一切看起来都很好......

我只是不明白为什么会发生这种情况。我在想,也许 spring bean 工厂正在尝试制作多个后存储库 bean,但没有理由这样做......

我想也许我只是错过了配置(但事实并非如此,因为 Spring Boot 项目的主要方法有 @SpringBootApplication ,它负责所有这些)。

然后我想我需要添加 @Transactional关于JpaRepository接口(interface),但如果我从 Spring Boot Data 文档中正确理解了这一点,情况就不是这样了……我需要为两个 JpaRepository 接口(interface)设置 bean 名称属性吗?

如果是这样,为什么? :) 构造函数不会使用不同的类名称(PostRepository 与 UserRepository)吗?

最佳答案

这两个建议都没有帮助,正如我之前提到的和现在研究的 Spring boot 一样,您实际上并不需要 @Repository 或使用 @EnableJpaRepositories("package.name") 因为 @SpringBootApplication 会为您完成所有扫描,只要您的存储库位于同一个包中。如果一个实体的一个包中有一个存储库,另一个实体和另一个存储库的另一个包中有一个存储库,则需要使用此限定符来确保正确扫描包。

该修复实际上完全不直观 - 我的 pom.xml 仍然引用了导致问题的 spring-boot-starter-data-jdbc 。注释掉之后,这个问题就解决了。

对于任何希望能够看到第一个版本与编辑版本之间的差异的人,您可以查看我的github here 。数据库是 MySQL,它有 2 个表,一张称为 post,一张称为本地运行的 user。希望它对将来的人有所帮助:) 谢谢您的回答。

关于java - 无法注册以 null 定义的 bean 'postRepository' 。具有该名称的 bean 已在 null 中定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58557334/

相关文章:

java - JPA:未通过 persist() 在数据库中创建实体

java - 通过 MockMvc 运行时,传递给 ControllerAdvice 的身份验证 token 为空

java - 带有 Java 11 : Unable to resolve persistence unit root URL 的 Spring Boot 2.1

java - Spring 启动 : Jersey ResourceConfig needs annotating?

java - AWS S3 与 Spring Boot 错误 "profile file cannot be null"

java - String.contains 找到一个子字符串但没有找到 Pattern.matches?

java - 有没有办法在 Eclipse Java 项目中组织源代码树?

C# - 我怎样才能拥有一个引用任何实现一组接口(interface)的对象的类型?

java - 传递 Spring 数据 JPA 和 hibernate 分离实体以保持多对多关系

java - 寻找有状态的单例 bean