Bean-компонент postRepository, определенный в null, не может быть зарегистрирован. Бин с таким именем уже определен в null - PullRequest
0 голосов
/ 25 октября 2019

Я работаю над простым бэкэндом блога при весенней загрузке как личный проект. Я делаю это как часть попытки взять Java Spring, и у меня возникают проблемы с кодом ниже (довольно много ...).

Я получаю именно эту ошибку: Компонент postRepository, определенный в null, не может быть зарегистрирован. Компонент с таким именем уже определен в null, а переопределение отключено.

Сам код изначально работал нормально, так как я использовал Hibernate, у меня было 2 DAO, 2 DAOImpls и я использовал их в классах обслуживаниясовершать звонки в БД и обратно. Все работало, как и ожидалось - полный список пользователей может быть возвращен, полный список сообщений может быть возвращен, отдельный пользователь / сообщение и т. Д. Все операции crud.

Если я правильно понимаю, переключиться на Spring Data JPAвсе, что мне нужно, это избавиться от DAO и DAOImplementations и иметь только один интерфейс для каждой сущности, который расширяет JpaRepository<T, T>, что обеспечит реализации для findById, findAll, save, delete, чтобы назвать несколько. Однако после внесения изменений, удаления DAO и DAOImplementations, а затем обновления 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

DAO с использованием данных Spring JPA

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
}

Post / UserService

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 Rest 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);
    }

}

Я удалил операторы импорта, так как все выглядит хорошо ...

IЯ просто не понимаю, почему это происходит. Я думал, что, возможно, фабрика bean-компонентов Spring пытается создать более одного bean-компонента после репозитория, но для этого нет причин ...

Я подумала, может быть, я просто пропустила конфигурацию (но это не так, посколькуосновной метод из проекта весенней загрузки @SpringBootApplication, который позаботится обо всем этом).

Тогда я подумал, что мне нужно добавить @Transactional на интерфейсах JpaRepository, но это не тот случай, если я правильно понял из документации Spring Boot Data ... Нужно ли мне устанавливать beanимя свойства для двух интерфейсов JpaRepository?

Если так, то почему? :) Разве конструкторы не использовали бы имя классов, которое отличается (PostRepository против UserRepository)?

1 Ответ

0 голосов
/ 25 октября 2019

Ни одно из предложений не помогло, как в Spring boot, как я уже упоминал ранее, и сейчас также исследуем, вам не нужно ни @Repository, ни использовать @EnableJpaRepositories("package.name"), поскольку @SpringBootApplication выполняет все сканирование за вас, пока вашрепозитории находятся в одном пакете. Если у вас есть один репозиторий в одном пакете для одной сущности и другой пакет для другой сущности и другого репозитория, вам нужно будет использовать этот квалификатор, чтобы убедиться, что пакеты сканируются правильно.

Исправление было на самом деле совершенно не интуитивно понятно - мой pom.xml все еще имел ссылку на spring-boot-starter-data-jdbc, что вызывало проблемы. После комментирования это было решено.

Для тех, кто хочет увидеть разницу от первой до отредактированной версии, вы можете проверить мой github здесь . База данных - MySQL, и в ней установлены 2 таблицы: одна называется post, а другая - локально запущенный пользователь. Надеюсь, это поможет кому-то в будущем :) Спасибо за ответы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...