[英]Hibernate many to many relationship
我正在嘗試映射我的數據庫表,以便可以在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;
}
*/
}
堆棧跟蹤:
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
您必須具有getId()
方法或帶有@Id
注釋的字段。 將您的注釋移至字段,一切都會正常。
另外,您的關系不是@OneToMany
。 作者不能成為許多書籍的作者嗎? 是@ManyToMany
。
您的問題還在於,您有兩個表,它們的調用方式相同。 將聯接表的名稱更改為book-author
或類似名稱。
您的聯接表的名稱不應與將其中一個表更改為book_author的名稱相同
@JoinTable(name = "book_author", joinColumns = { @JoinColumn(name = "book_id") }, inverseJoinColumns = { @JoinColumn(name = "author_id") })
問題是:
@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);
}
方法具有相同的默認“值”,並且Hibernate在輸入“ /”地址時無法確定從中選擇哪個方法。 解決方案只是添加不同的映射值:
@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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.