Я работаю над простым бэкэндом блога при весенней загрузке как личный проект. Я делаю это как часть попытки взять 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)?