我有以下实体:
@Entity
@Table(name = "BOOKS")
public class Book {
@Id
@GeneratedValue(generator = "SEQUENCE_UID", strategy = GenerationType.SEQUENCE)
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "BOOK_ID")
private List<Page> pages = new ArrayList<>();
...
...
public List<Page> getPages() {
return Collections.unmodifiableList(pages);
}
public void add(Page page){
this.pages.add(page);
}
}
@Entity
@Table(name = "PAGES")
public class Page {
@Id
@GeneratedValue(generator = "SEQUENCE_UID", strategy = GenerationType.SEQUENCE)
private Long id;
@Column(name = "COLOR", nullable = false)
private String color;
...
...
}
正如您所看到的,我在页面列表中使用了CascadeType.ALL,实际上,当我尝试创建新书时,我可以看到以下查询:
INSERT INTO PAGES (ID, COLOR) VALUES (?,?)
但后来我得到了这个例外:
Internal Exception: org.postgresql.util.PSQLException: ERROR: null value in column "book_id" violates not-null constraint
我正在使用EclipseLink和Spring-Data,这就是我创建新书的方式:
Page page = new Page();
page.setColor("RED");
Book book = new Book();
book.add(page);
bookRepository.save(book);
我在这里缺少什么?
答案 0 :(得分:1)
问题是两个类都没有自动生成id,所以你看到错误
错误:“book_id”列中的空值违反了非空约束
JPA实体对象不需要在
Book book = new Book();
book.setId(1L);
bookRepository.save(book);
但更容易使用生成价值战略:
@Entity
@Table(name = "BOOKS")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="BOOK_SEQ")
@SequenceGenerator(name="BOOK_SEQ", initialValue=1, allocationSize=1, sequenceName="BOOK_SEQ")
private Long id;
...
...
}
@Entity
@Table(name = "PAGES")
public class Page {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="PAGE_SEQ")
@SequenceGenerator(name="PAGE_SEQ", initialValue=1, allocationSize=1, sequenceName="PAGE_SEQ")
private Long id;
...
...
}
你需要在数据库上创建BOOK_SEQ和PAGE_SEQ,这取决于sql脚本可以更改的数据库,并非所有数据库都有序列,例如mysql不支持序列
如果你使用postgresql,你可以执行代码:
创建序列BOOK_SEQ 从1开始 增加1 maxvalue 10000 最小值1 周期; 创建序列PAGE_SEQ 从1开始 增加1 maxvalue 10000 最小值1 周期;
答案 1 :(得分:0)
找到this回答 - 事实上似乎有两个查询,所以not-null确实阻止了第二个查询。