I have 2 tables. Book
and Category
. A book can have multiple categories, and a category can have a list of book, right? So I create a new table category_book
to make a ManyToMany relationship, with only book_id(fk) and category_id(fk) in it.
My Book Entity:
@Id
@Column(name = "book_id", nullable = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE)
private int bookId;
@ManyToMany
@JoinTable(name = "category_book", joinColumns = @JoinColumn(name = "book_id"), inverseJoinColumns = @JoinColumn(name = "category_id"))
private List<CategoryEntity> categoriesList;
...other basic attributes and constructors and getters and setters.....
My Category Entity:
@Id
@Column(name = "category_id", nullable = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE)
private int categoryId;
@ManyToMany(mappedBy = "categoriesList", cascade = CascadeType.PERSIST)
private List<BookEntity> bookEntityList;
The servlet to add new book (categories already added seperately before.)
String[] category= request.getParameterValues("checkbox_category");
List<CategoryEntity> categoryEntityList = new ArrayList<>();
BookEntity newbook = new BookEntity();
for(String s: category){
CategoryEntity categoryEntity2 = new CategoryEntity();
categoryEntity2.setCategoryId(Integer.parseInt(s));
categoryEntityList.add(categoryEntity);
}
newbook.setCategories(categoryEntityList);
bookSessionBean.addBook(newbook);
BookSessionBean:
public void addBook(BookEntity book){
em.persist(book);
}
I checked many topics, but couldn't solve the problem. The error keeps showing.
Internal Exception: java.sql.SQLException: No database selected
Error Code: 1046
Call: INSERT INTO category_book (category_id, book_id) VALUES (?, ?)
bind => [2 parameters bound]
Query: DataModifyQuery(name="categoriesList" sql="INSERT INTO category_book (category_id, book_id) VALUES (?, ?)")
or
Error Code: 1046
Call: ALTER TABLE category_book ADD CONSTRAINT FK_category_book_category_id FOREIGN KEY (category_id) REFERENCES book.category (category_id)
Query: DataModifyQuery(sql="ALTER TABLE category_book ADD CONSTRAINT FK_category_book_category_id FOREIGN KEY (category_id) REFERENCES book.category (category_id)")
All other things can persist successfully, only this ManyToMany cause troubles.
UPDATE: It's not because of connection URL jdbc, I'm using connection pool to get database and it's correct. If I remove the all the @ManyToMany relationship related, it will run normal. But this time I need to use ManyToMany relationship.
The persistence.xml file:
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/book</jta-data-source>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
UPDATE 2: I just check clearly, I tried to remove all ManyToMany related, it's working perfectly, but since I add @ManyToMany back again, it gives many errors, even it's still deploys successfully (but can't add new book or add to new table category_book
via servlet and service session bean )
Still haven't find anything to solve this problem. Am I doing anything wrong?
Well, this can only mean you haven't configured the persistance.xml correctly.
The way the connection url should look like is:
"jdbc:databaseType://ip:port/databaseName"
example: "jdbc:mysql://localhost:3306/books"
So, after of hours and hours researching on the internet what's the problem, but no help. Then at some point I tried to look into the error message, and the problem is the one I find it hard to understand, no other place ever mentions it.
The error No Database Selected is because of the name column in the @ManyToMany @JoinTable annotation. I need to put the databasename.columnname
then it's working. But I check many many tutorials and some answers/questions here, they dont need databasename
, weird, right? And If I use @Column I dont need databasename
at all.
@Id
@Column(name = "book_id", nullable = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE)
private String bookId
@ManyToMany(cascade = CascadeType.MERGE)
@JoinTable(name = "book.category_book", joinColumns = @JoinColumn(name = "book_id"), inverseJoinColumns = @JoinColumn(name = "category_id"))
//The correct one. `book` is my databasename.
To get the code working more correctly, because in table category_book
I have 2 primary keys book_id
and category_id
(works as foreign key), I have to change the ArrayList to HashSet to allow duplicated keys.
private Set<CategoryEntity> categoriesList = new HashSet<>();
I remove casdade for CategoryEntity, add cascade MERGE for BookEntity.
Now everything's working and running.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.