gpt4 book ai didi

java - JPA @onetomany 级联插入正在抛出 org.hibernate.exception.ConstraintViolationException

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:06:29 25 4
gpt4 key购买 nike

附属类:

@Entity
@Table(name="attachments")
@Getter
@Setter
public class AttachmentModel {

//@EmbeddedId
//private AttachmentId attachmentId;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="notice_attachment_id")
private long attachmentId;

@Column(name="notice_id")
private long noticeId;

@Column(name="attachment")
private String attachmentUrl;

@JsonIgnore
@ManyToOne(cascade = {CascadeType.PERSIST , CascadeType.MERGE,
CascadeType.DETACH , CascadeType.REFRESH},optional = false)
@JoinColumn(name="notice_id", insertable=false, updatable=false)
@MapsId("notice_id")
NoticesModel notice;

public void addNotice(NoticesModel notice) {
this.notice = notice;
}

public AttachmentModel() {

}
}

通知类:

@Entity
@Table(name = "notices")
@Getter @Setter
public class NoticesModel {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "notice_id" ,updatable = false, nullable = false,insertable = true)
private long noticeID;

@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL } , mappedBy = "notice")
//@mappedBy(name = "notice_id")
private List<AttachmentModel> attachments;
}

解析JSON并保存的代码

public HashMap<String,Object> saveNotices(@RequestBody List<NoticesModel> tmpNotices)
{
List<NoticesModel> notices = tmpNotices;
for (NoticesModel notice : notices) {
List<AttachmentModel> attachments = notice.getAttachments();
for (AttachmentModel attachment : attachments) {
attachment.addNotice(notice);
System.out.println(attachment.getAttachmentUrl());
}

for (AttachmentModel attachment : attachments) {
//attachment.addNotice(notice);
System.out.println(attachment.getNotice().getContent());
System.out.println(attachment.getNotice().getNoticeID());
}
}
int result = noticesServices.saveNotice(notices);

HashMap<String,Object> res = new HashMap<>();
res.put("message",result);
return res;

}

这是我要发送的 JSON

[
{
"attachments": [
{
"attachmentUrl": "/abc/bcd"
}
],
"content": "string",
}
]

对于这种情况,我试图保存我的通知和附件。在这种特殊情况下,notice_id 是在保存到数据库时创建的。

因此在尝试保存附件表时,它试图将 notice_id 保存为 0。

所以我得到了异常(exception)。

无法执行语句; SQL [不适用];约束 [attachments_notices_fk];嵌套异常是 org.hibernate.exception.ConstraintViolationException: 无法执行语句

我怎样才能解决这个问题?是否可以在保存到数据库之前获取 notice_id,以便我可以获得 notice_id 以便我可以将其设置在附件中,这样它就不会被保存为 0?在这种情况下(我是 JPA 和 springboot 的新手)我做错了什么(我可以采取任何替代方法)?

最佳答案

我认为您不需要使用任何 notice_id。从你的 AttachmentModel 中删除 notice_id 和相关的东西,并使用 notice 进行映射(注意:仍然会有列 notice_id在删除后的数据库中),所以:

@ManyToOne
private NoticesModel notice;

并更改 NoticesModel 中的映射以引用正确的字段:

//                                    ALL is just a suggestion
@OneToMany(mappedBy = "noticesModel", cascade = CascadeType.ALL)
private List<AttachmentModel> attachementModels;

那么你的 for 循环可能看起来像:

for (NoticesModel notice : notices) {
for (AttachmentModel am : notice.getAttachments()) {
am.setNotice(notice);
}
noticesServices.save(notice);
}

您还可以在 NoticesModel 中添加类似这样的内容,以便在持久化之前始终处理设置引用:

@PrePersist
private void prePersist() {
for (AttachmentModel am : attachments) {
am.setNotice(this);
}
}

关于java - JPA @onetomany 级联插入正在抛出 org.hibernate.exception.ConstraintViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54233870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com