admin管理员组文章数量:1123401
I have two entities for RfidTags and Persons. One RfidTag is assigned to one Person. One Person can have one RfidTag. If I delete a Person that has an RfidTag, the assigned RfidTag should not get deleted, it should remain in the database, but the value for person_id should be set to NULL. I already have my SQL like this, but it is not working:
ALTER TABLE `rfid_tags`
ADD CONSTRAINT `FK_Rfid_Tag_Person`
FOREIGN KEY (`person_id`) REFERENCES `persons`(`id`)
ON DELETE SET NULL;
And here are my entities. I have already searched a lot and tried different things like changing the CascadeTypes or adding @OnDelete(onDeleteAction=SET_NULL), but nothing is working. Either the RfidTag will also get deleted (which I do not want) or I get an error like: org.hibernate.TransientObjectException: persistent instance references an unsaved transient instance of 'PersonEntity' (save the transient instance before flushing)
@Getter
@Setter
@Entity
@Table(name = "persons")
public class PersonEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "person", cascade = CascadeType.DETACH)
private RfidEntity rfid;
}
@Getter
@Setter
@Entity
@Table(name = "rfid_tags")
public class RfidEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Column(nullable = false)
private String label;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="person_id", referencedColumnName="id")
private PersonEntity person;
}
I have already searched a lot and tried different things like changing the CascadeTypes or adding @OnDelete(onDeleteAction=SET_NULL)
I have two entities for RfidTags and Persons. One RfidTag is assigned to one Person. One Person can have one RfidTag. If I delete a Person that has an RfidTag, the assigned RfidTag should not get deleted, it should remain in the database, but the value for person_id should be set to NULL. I already have my SQL like this, but it is not working:
ALTER TABLE `rfid_tags`
ADD CONSTRAINT `FK_Rfid_Tag_Person`
FOREIGN KEY (`person_id`) REFERENCES `persons`(`id`)
ON DELETE SET NULL;
And here are my entities. I have already searched a lot and tried different things like changing the CascadeTypes or adding @OnDelete(onDeleteAction=SET_NULL), but nothing is working. Either the RfidTag will also get deleted (which I do not want) or I get an error like: org.hibernate.TransientObjectException: persistent instance references an unsaved transient instance of 'PersonEntity' (save the transient instance before flushing)
@Getter
@Setter
@Entity
@Table(name = "persons")
public class PersonEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "person", cascade = CascadeType.DETACH)
private RfidEntity rfid;
}
@Getter
@Setter
@Entity
@Table(name = "rfid_tags")
public class RfidEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Column(nullable = false)
private String label;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="person_id", referencedColumnName="id")
private PersonEntity person;
}
I have already searched a lot and tried different things like changing the CascadeTypes or adding @OnDelete(onDeleteAction=SET_NULL)
Share Improve this question edited 14 hours ago Dalija Prasnikar♦ 28.5k45 gold badges94 silver badges175 bronze badges asked 14 hours ago user24707318user24707318 32 bronze badges New contributor user24707318 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 2- did you try cascade change on PersonEntity and allowing PersonEntity to be set as null? @OneToOne(fetch = FetchType.LAZY, mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true) private RfidEntity rfid; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "person_id", referencedColumnName = "id", nullable = true) private PersonEntity person; – Narendran Solai Sridharan Commented 14 hours ago
- @NarendranSolaiSridharan I just tried it, but when I delete a Person it also deletes the RfidTag, which I do not want. Thanks for your help! – user24707318 Commented 14 hours ago
2 Answers
Reset to default 1Hibernate does not automatically handle ON DELETE SET NULL
. You need to manually set the association to NULL
before deleting the PersonEntity
.
1. Update RfidEntity
Mapping
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id", referencedColumnName = "id", nullable = true)
private PersonEntity person;
2. Remove Cascade from PersonEntity
@OneToOne(fetch = FetchType.LAZY, mappedBy = "person")
private RfidEntity rfid;
3. Manually Set person
to NULL
Before Deletion
@Transactional
public void deletePerson(String personId) {
PersonEntity person = personRepository.findById(personId).orElseThrow();
if (person.getRfid() != null) {
person.getRfid().setPerson(null);
rfidRepository.save(person.getRfid());
}
personRepository.delete(person);
}
4. Verify SQL Constraint
ALTER TABLE `rfid_tags`
ADD CONSTRAINT `FK_Rfid_Tag_Person`
FOREIGN KEY (`person_id`) REFERENCES `persons`(`id`)
ON DELETE SET NULL;
Note: Hibernate doesn’t enforce ON DELETE SET NULL
; it must be handled explicitly in the application logic.
Please try using the below in Person entity:
// No cascade type here; we don’t want cascading from Person to Rfid
@OneToOne(fetch = FetchType.LAZY, mappedBy = "person")
private RfidEntity rfid;
And in RfidTags
@OneToOne(fetch = FetchType.LAZY, orphanRemoval = false, cascade = {})
@JoinColumn(name = "person_id", referencedColumnName = "id", onDelete = OnDeleteAction.CASCADE)
private Person person;
本文标签: javaSpring Data JPA OneToOne ON DELETE SET NULLStack Overflow
版权声明:本文标题:java - Spring Data JPA OneToOne ON DELETE SET NULL - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736567475a1944725.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论