我想在我自己的項目中使用H2數據庫複製休眠示例from here - 使用H2數據庫 - 使用Flyway遷移初始化 - 以及Spring Data。問題是,當我保存父對象BookCategory時,它還保存了孩子(Book對象),但它不保存book_category_id,即「孩子」對象的「父母ID」!休眠不爲OneToMany兒童保存父母ID
我的SQL是這樣的:
CREATE SEQUENCE SEQ_IDNUMS START WITH 1;
CREATE TABLE book_category (
id int(11) NOT NULL,
name varchar(255) NOT NULL,
PRIMARY KEY (id,name)
);
CREATE TABLE book (
id int(11) NOT NULL,
name varchar(255) DEFAULT NULL,
book_category_id int(11) DEFAULT NULL
);
alter table book add constraint pk_book_id PRIMARY KEY (id);
alter table book add constraint fk_book_bookcategoryid FOREIGN KEY(book_category_id) REFERENCES book_category(id) ON DELETE CASCADE;
然後,我的書類:
import javax.persistence.*;
@Entity
public class Book{
private int id;
private String name;
private BookCategory bookCategory;
public Book() { }
public Book(String name) { this.name = name; }
@Id
@SequenceGenerator(name = "seq_idnums", sequenceName = "seq_idnums", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_idnums")
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; }
@ManyToOne
@JoinColumn(name = "book_category_id")
public BookCategory getBookCategory() { return bookCategory; }
public void setBookCategory(BookCategory bookCategory) { this.bookCategory = bookCategory; }
}
而且我BookCategory類:
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name = "book_category")
public class BookCategory {
private int id;
private String name;
private Set<Book> books;
public BookCategory(){ }
public BookCategory(String name, Set<Book> books) {
this.name = name;
this.books = books;
}
@Id
@SequenceGenerator(name = "seq_idnums", sequenceName = "seq_idnums", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_idnums")
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; }
@OneToMany(mappedBy = "bookCategory", cascade = CascadeType.ALL)
public Set<Book> getBooks() { return books; }
public void setBooks(Set<Book> books) { this.books = books; }
}
至於儲蓄的一部分,我m完全按照示例進行:
BookCategory categoryA = new BookCategory("Category A", new HashSet<Book>(){{
add(new Book("Book A1"));
add(new Book("Book A2"));
add(new Book("Book A3"));
}});
BookCategory categoryB = new BookCategory("Category B", new HashSet<Book>(){{
add(new Book("Book B1"));
add(new Book("Book B2"));
add(new Book("Book B3"));
}});
bookCategoryRepository.save(new HashSet<BookCategory>() {{
add(categoryA);
add(categoryB);
}});
最後,我BookCategoryRepository看上去只有這樣,由於春季數據法寶:
import org.springframework.data.repository.CrudRepository;
public interface BookCategoryRepository extends CrudRepository<BookCategory, Long> {
}
這個問題已經被問了幾次,如here。在那裏,接受的答案基本上說,與@JoinColumn
一側是應該堅持的一面。正如你在上面的代碼中看到的那樣,我正在複製的例子並沒有這樣做,而是堅持了另一方,而且這對於作者來說顯然工作得很好。如果我會盡力堅持書對象,而不是,我得到這個異常:
[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : Book.bookCategory -> BookCategory; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : Book.bookCategory -> BookCategory] with root cause
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : Book.bookCategory -> BookCategory
......所以這不是解決辦法。
現在,另一個問題here及其答案表明問題是id列必須爲空。然而,這導致遷飛路線錯誤,那麼,我真的不希望有我的ID字段可爲空反正:
Invocation of init method failed; nested exception is org.flywaydb.core.internal.dbsupport.FlywaySqlScriptException: Error executing statement at line 14: alter table book add constraint pk_book_id PRIMARY KEY (id)
另一個問題here認爲,「nullable = false
」必須拆除,但首先我沒有這個。
我完全處於虧損狀態。什麼可能有錯誤,以及如何解決它?
您正在創建一本新書'新書(「書A1」)',但您不在此新書對象中設置'bookCategory'字段。你可以設置該字段並嘗試。另一方面,我通常會將實體傳遞給'repository'上的'save'方法。從來沒有嘗試像你一樣傳遞一個HashSet像bookCategoryRepository.save(new HashSet()'。這是否工作? –