我试图映射我的数据库表,以便我可以在Books和Author表之间建立多对多的关系。
首先,它是一对多的关系设计,感谢@xenteros和@Amer Qarabsa,我开始将它重新设计成多对多的关系。
作者(型号)类:
Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "author_id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "surname")
private String surname;
@Column(name = "date_of_birth")
private Date dateOfBirth;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "book_author",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
private Set<Book> authorsBooks = new HashSet<Book>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Set<Book> getAuthorsBooks() {
return authorsBooks;
}
public void setAuthorsBooks(Set<Book> authorsBooks) {
this.authorsBooks = authorsBooks;
}
}
预订(模特)课程:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "book_id")
private int bookId;
@Column(name = "title")
private String title;
@Column(name = "title_original")
private String titleOriginal;
@Column(name = "premiere_date")
private Date premiereDate;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "book_author", joinColumns = { @JoinColumn(name = "book_id") }, inverseJoinColumns = { @JoinColumn(name = "author_id") })
private Set<Author> booksAuthors = new HashSet<Author>(0);
public int getBookId() {
return bookId;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleOriginal() {
return titleOriginal;
}
public void setTitleOriginal(String titleOriginal) {
this.titleOriginal = titleOriginal;
}
public Date getPremiereDate() {
return premiereDate;
}
public void setPremiereDate(Date premiereDate) {
this.premiereDate = premiereDate;
}
public Set<Author> getBookAuthors() {
return this.booksAuthors;
}
public void setBookAuthors(Set<Author> bookAuthors) {
this.booksAuthors = bookAuthors;
}
}
AuthorController 类:
@Controller
public class AuthorController {
@Autowired
private AuthorRepository authorRepository;
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Author>> getAuthors() {
return new ResponseEntity<>(authorRepository.findAll(), HttpStatus.OK);
}
@RequestMapping(value = "/authors/{id}", method = RequestMethod.GET)
public ResponseEntity<Author> getAuthor(@PathVariable int id) {
Author author = authorRepository.findOne(id);
if (author != null) {
return new ResponseEntity<>(authorRepository.findOne(id), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addAuthor(@RequestBody Author author) {
return new ResponseEntity<>(authorRepository.save(author), HttpStatus.CREATED);
}
@RequestMapping(value = "/authors/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteAuthor(@PathVariable int id) {
authorRepository.delete(id);
return new ResponseEntity<Void>(HttpStatus.OK);
}
/*
@RequestMapping(value = {"/authors"}, method = RequestMethod.GET)
public ModelAndView allAuthors() {
ModelAndView modelAndView = new ModelAndView("authors/home"); //viewname przekazujemy z folderu templates
List<Author> author = authorService.getAllAuthors();
modelAndView.addObject("authors",author); //ta nazwa tutaj "authors" sluzy potem do wykorzystania jej w templacie
return modelAndView;
}
*/
}
BookController 类:
@Controller
public class BookController {
@Autowired
private BookRepository bookRepository;
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Book>> getBooks() {
return new ResponseEntity<>(bookRepository.findAll(), HttpStatus.OK);
}
@RequestMapping(value = "/books/{id}", method = RequestMethod.GET)
public ResponseEntity<Book> getBook(@PathVariable int id) {
Book book = bookRepository.findOne(id);
if (book != null) {
return new ResponseEntity<>(bookRepository.findOne(id), HttpStatus.OK);
} else {
return new ResponseEntity<>( HttpStatus.NOT_FOUND);
}
}
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addBook(@RequestBody Book book) {
return new ResponseEntity<>(bookRepository.save(book), HttpStatus.CREATED);
}
@RequestMapping(value = "/books/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteBook(@PathVariable int id) {
bookRepository.delete(id);
return new ResponseEntity<Void>(HttpStatus.OK);
}
/*
@RequestMapping(value = {"/books"}, method = RequestMethod.GET)
public ModelAndView allBooks() {
ModelAndView modelAndView = new ModelAndView("books/home"); //viewname przekazujemy z folderu templates
List<Book> book = bookService.getAllBooks();
modelAndView.addObject("books",book); //ta nazwa tutaj "books" sluzy potem do wykorzystania jej w templacie
return modelAndView;
}
*/
}
Stacktrace:
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-07 13:02:18.638 ERROR 6812 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'bookController' method
public org.springframework.http.ResponseEntity<?> eu.fitk.controller.BookController.addBook(eu.fitk.model.Book)
to {[],methods=[POST]}: There is already 'authorController' bean method
public org.springframework.http.ResponseEntity<?> eu.fitk.controller.AuthorController.addAuthor(eu.fitk.model.Author) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at eu.fitk.BookwebApplication.main(BookwebApplication.java:9) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.6.RELEASE.jar:1.5.6.RELEASE]
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'bookController' method
public org.springframework.http.ResponseEntity<?> eu.fitk.controller.BookController.addBook(eu.fitk.model.Book)
to {[],methods=[POST]}: There is already 'authorController' bean method
public org.springframework.http.ResponseEntity<?> eu.fitk.controller.AuthorController.addAuthor(eu.fitk.model.Author) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:540) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:264) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:250) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:214) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:184) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:127) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
... 21 common frames omitted
Process finished with exit code 0
答案 0 :(得分:1)
您必须拥有getId()
方法或使用@Id
注释的字段。将注释移动到字段,一切都会正常工作。
此外,您的关系不是@OneToMany
。作者不能成为很多书的作者吗?它是@ManyToMany
。
您的问题也在于,您有两个以相同方式调用的表。将联接表的名称更改为book-author
或类似名称。
答案 1 :(得分:1)
您的联接表的名称不应与您的某个表相同 例如改为book_author
@JoinTable(name = "book_author", joinColumns = { @JoinColumn(name = "book_id") }, inverseJoinColumns = { @JoinColumn(name = "author_id") })
答案 2 :(得分:0)
问题在于:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addBook(@RequestBody Book book) {
return new ResponseEntity<>(bookRepository.save(book), HttpStatus.CREATED);
}
@RequestMapping(value="/addauthor", method = RequestMethod.POST)
public ResponseEntity<?> addAuthor(@RequestBody Author author) {
return new ResponseEntity<>(authorRepository.save(author), HttpStatus.CREATED);
}
方法具有相同的默认值&#34;值&#34;并且在进入&#34; /&#34;时,Hibernate无法确定从中选择哪一个。 ADRESS。解决方案只是添加不同的映射值:
@RequestMapping(value="/addauthor", method = RequestMethod.POST)
public ResponseEntity<?> addAuthor(@RequestBody Author author) {
return new ResponseEntity<>(authorRepository.save(author), HttpStatus.CREATED);
}
@RequestMapping(value = "/addbook", method = RequestMethod.POST)
public ResponseEntity<?> addBook(@RequestBody Book book) {
return new ResponseEntity<>(bookRepository.save(book), HttpStatus.CREATED);
}