JPA serializing/deserializing 嵌套的自动生成字段
JPA serializing/deserializing nested autogenerated fields
Spring-boot中有这样一个项目:
模型页面:
@Entity
@Table(name = "pages")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Page implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "color")
private String color;
@OneToMany(mappedBy = "page", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Note> note;
// constructor, getters and setters
模型注释(一页可以有很多注释,notes.page_id是pages.id的外键):
@Entity
@Table(name = "notes")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Note implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "content")
private String content;
@Column(name = "title")
private String title;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "page_id")
private Page page;
// constructor, getters and setters
控制器:
public ResponseEntity<Object> createPage(@RequestBody Page page) {
pageRepository.saveAndFlush(page);
return new ResponseEntity("OK", HttpStatus.OK);
}
当我使用以下 Json 请求正文向端点发出 Post 请求时
{
"id": null,
"color": "yellow",
"note": [
{
"id": null,
"title": "Java",
"content": "Java is awesome",
"page": null
},
{
"id": null,
"title": "Python",
"content": "Python is good",
"page": null
}
]
}
新记录已写入数据库,页面 ID 和注释 ID 已正确生成,但字段 notes.page_id 仍为空。
Table pages
:
id|color |
1 |yellow |
Table notes
:
id| content |title |page_id|
1 | Java is awesome|Java | null |
2 | Python is good |Python| null |
问题是:如何为 notes.page_id 提供 pages
table 的自动生成 ID?
JPA实体的原理其实很简单。
您的 JPA 实体中有一个字段,它映射到数据库中的一个列 table。
此字段包含的内容写入 table 中相应的数据库列。
您的 Node.page
字段是映射到 note.page_id
列的字段。
而该字段的值为null
。所以写入数据库列的是null
。
如果要在列中包含页面 ID,则需要在此字段中包含非空 page
。所以你的代码需要做
page.getNotes().forEach(note -> note.setPage(page))
就这么简单和合乎逻辑。
修改您的注释 Class 代码如下
@ManyToOne
@JoinColumn(name="page_id", nullable=false)
private Page page;
Spring-boot中有这样一个项目:
模型页面:
@Entity
@Table(name = "pages")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Page implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "color")
private String color;
@OneToMany(mappedBy = "page", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Note> note;
// constructor, getters and setters
模型注释(一页可以有很多注释,notes.page_id是pages.id的外键):
@Entity
@Table(name = "notes")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Note implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "content")
private String content;
@Column(name = "title")
private String title;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "page_id")
private Page page;
// constructor, getters and setters
控制器:
public ResponseEntity<Object> createPage(@RequestBody Page page) {
pageRepository.saveAndFlush(page);
return new ResponseEntity("OK", HttpStatus.OK);
}
当我使用以下 Json 请求正文向端点发出 Post 请求时
{
"id": null,
"color": "yellow",
"note": [
{
"id": null,
"title": "Java",
"content": "Java is awesome",
"page": null
},
{
"id": null,
"title": "Python",
"content": "Python is good",
"page": null
}
]
}
新记录已写入数据库,页面 ID 和注释 ID 已正确生成,但字段 notes.page_id 仍为空。
Table pages
:
id|color |
1 |yellow |
Table notes
:
id| content |title |page_id|
1 | Java is awesome|Java | null |
2 | Python is good |Python| null |
问题是:如何为 notes.page_id 提供 pages
table 的自动生成 ID?
JPA实体的原理其实很简单。
您的 JPA 实体中有一个字段,它映射到数据库中的一个列 table。
此字段包含的内容写入 table 中相应的数据库列。
您的 Node.page
字段是映射到 note.page_id
列的字段。
而该字段的值为null
。所以写入数据库列的是null
。
如果要在列中包含页面 ID,则需要在此字段中包含非空 page
。所以你的代码需要做
page.getNotes().forEach(note -> note.setPage(page))
就这么简单和合乎逻辑。
修改您的注释 Class 代码如下
@ManyToOne
@JoinColumn(name="page_id", nullable=false)
private Page page;