ฉันได้รับข้อผิดพลาดต่อไปนี้เมื่อฉันบันทึกวัตถุโดยใช้ Hibernate
object references an unsaved transient instance - save the transient instance before flushing
ฉันได้รับข้อผิดพลาดต่อไปนี้เมื่อฉันบันทึกวัตถุโดยใช้ Hibernate
object references an unsaved transient instance - save the transient instance before flushing
คำตอบ:
คุณควรรวมcascade="all"
(หากใช้ xml) หรือcascade=CascadeType.ALL
(หากใช้คำอธิบายประกอบ) ในการจับคู่คอลเล็กชันของคุณ
สิ่งนี้เกิดขึ้นเนื่องจากคุณมีคอลเล็กชันในเอนทิตีของคุณและคอลเลกชันนั้นมีหนึ่งรายการขึ้นไปซึ่งไม่ปรากฏในฐานข้อมูล ด้วยการระบุตัวเลือกข้างต้นคุณจะบอกให้จำศีลเพื่อบันทึกลงในฐานข้อมูลเมื่อบันทึกพาเรนต์
ผมเชื่อว่านี่อาจจะเป็นคำตอบเพียงแค่ทำซ้ำ แต่เพียงชี้แจงผมได้รับนี้ในการทำแผนที่เช่นเดียวกับ@OneToOne
@OneToMany
ในทั้งสองกรณีมันเป็นความจริงที่ว่าChild
วัตถุที่ฉันเพิ่มลงไปนั้นParent
ยังไม่ได้บันทึกในฐานข้อมูล ดังนั้นเมื่อผมเพิ่มChild
ไปParent
ที่บันทึกไว้แล้วParent
, Hibernate จะโยน"object references an unsaved transient instance - save the transient instance before flushing"
ข้อความเมื่อมีการบันทึกผู้ปกครอง
เพิ่มในcascade = {CascadeType.ALL}
ในParent's
การอ้างอิงถึงChild
แก้ปัญหาในทั้งสองกรณี นี้ที่บันทึกไว้และChild
Parent
ขออภัยสำหรับคำตอบที่ทำซ้ำเพียงต้องการชี้แจงเพิ่มเติมสำหรับคน
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
return performanceLog;
}
new MyEntity
(โดยไม่ต้องซิงโครไนซ์กับฐานข้อมูล - ฟลัชชิง) แทนที่จะได้รับอินสแตนซ์ที่ซิงโครไนซ์จากฐานข้อมูล การทำแบบสอบถามไฮเบอร์เนตโดยใช้อินสแตนซ์นั้นจะแจ้งให้คุณทราบว่าสิ่งที่คุณคาดหวังว่าจะอยู่ในฐานข้อมูลนั้นแตกต่างจากสิ่งที่คุณมีในหน่วยความจำของแอป ในกรณีนี้ - เพียงแค่ซิงโครไนซ์ / รับเอนทิตีของคุณจากฐานข้อมูลและใช้มัน ไม่จำเป็นต้องใช้ CascadeType.ALL
สิ่งนี้จะเกิดขึ้นเมื่อบันทึกวัตถุเมื่อ Hibernate คิดว่าต้องบันทึกวัตถุที่เกี่ยวข้องกับวัตถุที่คุณกำลังบันทึก
ฉันมีปัญหานี้และไม่ต้องการบันทึกการเปลี่ยนแปลงกับวัตถุที่อ้างอิงดังนั้นฉันต้องการให้ชนิดของการเรียงซ้อนเป็นไม่มี
เคล็ดลับคือเพื่อให้แน่ใจว่า ID และ VERSION ในวัตถุที่อ้างอิงถูกตั้งค่าเพื่อให้ไฮเบอร์เนตไม่คิดว่าวัตถุที่อ้างอิงเป็นวัตถุใหม่ที่ต้องการการบันทึก สิ่งนี้ใช้ได้สำหรับฉัน
ดูความสัมพันธ์ทั้งหมดในคลาสที่คุณกำลังบันทึกเพื่อทำงานกับวัตถุที่เกี่ยวข้อง (และวัตถุที่เกี่ยวข้องของวัตถุที่เกี่ยวข้อง) และตรวจสอบให้แน่ใจว่า ID และ VERSION ถูกตั้งค่าในวัตถุทั้งหมดของแผนผังวัตถุ
ตามที่ฉันอธิบายในบทความนี้เมื่อใช้ JPA และ Hibernate เอนทิตีสามารถอยู่ในสถานะใดสถานะหนึ่งใน 4 สถานะต่อไปนี้:
ใหม่ - วัตถุที่สร้างขึ้นใหม่ที่ไม่เคยเกี่ยวข้องกับ Hibernate Session (aka Persistence Context) และไม่ได้ถูกแมปกับแถวของตารางฐานข้อมูลใด ๆ จะถือว่าอยู่ในสถานะใหม่หรือชั่วคราว
ในการที่จะคงอยู่เราต้องเรียกpersist
วิธีการอย่างชัดเจนหรือใช้กลไกการคงอยู่ของสกรรมกริยา
Persistent - เอนทิตีแบบถาวรนั้นเชื่อมโยงกับแถวตารางฐานข้อมูลและมีการจัดการโดย Persistence Context ที่กำลังรันอยู่
การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นกับเอนทิตีดังกล่าวจะถูกตรวจพบและแพร่กระจายไปยังฐานข้อมูล (ในระหว่างช่วงเวลาล้างเซสชัน)
Detached - เมื่อบริบทการคงอยู่ที่รันอยู่ในปัจจุบันถูกปิดเอนทิตีที่ได้รับการจัดการก่อนหน้านี้ทั้งหมดจะถูกแยกออก การเปลี่ยนแปลงที่สำเร็จจะไม่ถูกติดตามอีกต่อไปและจะไม่มีการซิงโครไนซ์ฐานข้อมูลอัตโนมัติเกิดขึ้น
ลบออก - แม้ว่า JPA จะต้องการให้ลบเอนทิตีที่ได้รับการจัดการเท่านั้น แต่ไฮเบอร์เนตยังสามารถลบเอนทิตีที่แยกออกได้ (แต่ผ่านremove
การเรียกเมธอดเท่านั้น)
ที่จะย้ายกิจการจากรัฐหนึ่งไปที่อื่น ๆ คุณสามารถใช้persist
, remove
หรือmerge
วิธีการ
ปัญหาที่คุณอธิบายในคำถามของคุณ:
object references an unsaved transient instance - save the transient instance before flushing
เกิดจากการเชื่อมโยงนิติบุคคลในรัฐที่ ใหม่ไปยังหน่วยงานที่อยู่ในรัฐของการบริหารจัดการ
สิ่งนี้สามารถเกิดขึ้นได้เมื่อคุณเชื่อมโยงเอนทิตีลูกกับคอลเลกชันแบบหนึ่งต่อหลายในเอนทิตีหลักและการรวบรวมไม่ได้cascade
เป็นการเปลี่ยนสถานะเอนทิตี
ดังนั้นตามที่ฉันอธิบายไว้ในบทความนี้คุณสามารถแก้ไขได้โดยการเพิ่มการเชื่อมโยงเอนทิตีที่ก่อให้เกิดความล้มเหลวนี้ดังนี้
@OneToOne
สมาคม@OneToOne(
mappedBy = "post",
orphanRemoval = true,
cascade = CascadeType.ALL)
private PostDetails details;
สังเกตเห็น
CascadeType.ALL
ค่าที่เราเพิ่มสำหรับcascade
แอตทริบิวต์
@OneToMany
สมาคม@OneToMany(
mappedBy = "post",
orphanRemoval = true,
cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();
อีกครั้งCascadeType.ALL
เหมาะสำหรับการเชื่อมโยงแบบสองทิศทาง@OneToMany
ขณะนี้เพื่อให้การเรียงซ้อนทำงานอย่างถูกต้องในแบบสองทิศทางคุณต้องตรวจสอบให้แน่ใจว่าการเชื่อมโยงหลักและลูกเชื่อมโยงกัน
ตรวจสอบบทความนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่ดีที่สุดในการบรรลุเป้าหมายนี้
@ManyToMany
สมาคม@ManyToMany(
mappedBy = "authors",
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}
)
private List<Book> books = new ArrayList<>();
ในการ@ManyToMany
เชื่อมโยงคุณไม่สามารถใช้CascadeType.ALL
หรือorphanRemoval
จะเป็นการเผยแพร่การเปลี่ยนสถานะลบเอนทิตีจากพาเรนต์หนึ่งไปยังเอนทิตีหลัก
ดังนั้นสำหรับการ@ManyToMany
เชื่อมโยงคุณมักจะเรียงซ้อนCascadeType.PERSIST
หรือCascadeType.MERGE
ดำเนินการ หรือคุณสามารถขยายที่หรือDETACH
REFRESH
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่ดีที่สุดในการจับคู่
@ManyToMany
สมาคมลองดูบทความนี้เช่นกัน
หรือหากคุณต้องการใช้ "กำลัง" น้อยที่สุด (เช่นหากคุณไม่ต้องการลบการเรียงซ้อน) เพื่อให้ได้สิ่งที่ต้องการให้ใช้
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
...
@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;
@ManyToMany(cascade={PERSIST, MERGE, REFRESH, DETACH})
( แต่นำออก) ไม่น้ำตกการปรับปรุงเช่นของ Hibernate CascadeType.SAVE_UPDATE
ไม่
ในกรณีของฉันมันก็เกิดจากการที่ไม่ได้มีCascadeType
ใน@ManyToOne
ด้านของความสัมพันธ์แบบสองทิศทาง จะแม่นยำมากขึ้นผมก็มีCascadeType.ALL
อยู่บนด้านข้างและไม่ได้มีไว้ใน@OneToMany
@ManyToOne
การเพิ่มCascadeType.ALL
เพื่อ@ManyToOne
แก้ไขปัญหา
หนึ่งต่อหลายด้าน:
@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;
หลายต่อหลายด้าน (ทำให้เกิดปัญหา)
@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
แบบตัวต่อตัว (แก้ไขโดยการเพิ่มCascadeType.PERSIST
)
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
สิ่งนี้เกิดขึ้นกับฉันเมื่อยังคงเอนทิตีที่ระเบียนที่มีอยู่ในฐานข้อมูลมีค่า NULL สำหรับฟิลด์ที่ใส่คำอธิบายประกอบด้วย @Version (สำหรับการล็อกในแง่ดี) การอัพเดตค่า NULL เป็น 0 ในฐานข้อมูลแก้ไขปัญหานี้
นี่ไม่ใช่เหตุผลเดียวสำหรับข้อผิดพลาด ตอนนี้ฉันพบข้อผิดพลาดการพิมพ์ผิดที่ฉันเชื่อว่าตั้งค่าของเอนทิตีที่ถูกบันทึกไว้แล้ว
X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);
ฉันพบข้อผิดพลาดโดยการค้นหาว่าตัวแปรตัวใดที่ทำให้เกิดข้อผิดพลาด (ในกรณีนี้String xid
) ฉันใช้catch
โค้ดทั้งบล็อกที่บันทึกเอนทิตีและพิมพ์การติดตาม
{
code block that performed the operation
} catch (Exception e) {
e.printStackTrace(); // put a break-point here and inspect the 'e'
return ERROR;
}
อย่าใช้Cascade.All
จนกว่าคุณจะต้องทำจริงๆ Role
และPermission
มีmanyToMany
ความสัมพันธ์แบบสองทิศทาง จากนั้นรหัสต่อไปนี้จะทำงานได้ดี
Permission p = new Permission();
p.setName("help");
Permission p2 = new Permission();
p2.setName("self_info");
p = (Permission)crudRepository.save(p); // returned p has id filled in.
p2 = (Permission)crudRepository.save(p2); // so does p2.
Role role = new Role();
role.setAvailable(true);
role.setDescription("a test role");
role.setRole("admin");
List<Permission> pList = new ArrayList<Permission>();
pList.add(p);
pList.add(p2);
role.setPermissions(pList);
crudRepository.save(role);
ในขณะที่ถ้าวัตถุเป็นเพียง "ใหม่" แล้วมันจะโยนข้อผิดพลาดเดียวกัน
หากคอลเลกชันของคุณเป็นโมฆะลอง: object.SetYouColection(null);
ในการเพิ่ม 2 เซ็นต์ของฉันฉันได้รับปัญหาเดียวกันนี้เมื่อฉันส่งnull
เป็น ID โดยไม่ได้ตั้งใจ ด้านล่างรหัสแสดงให้เห็นถึงสถานการณ์ของฉัน(และ OP ไม่ได้กล่าวถึงสถานการณ์ที่เฉพาะเจาะจงใด ๆ )
Employee emp = new Employee();
emp.setDept(new Dept(deptId)); // --> when deptId PKID is null, same error will be thrown
// calls to other setters...
em.persist(emp);
ที่นี่ฉันตั้งค่ารหัสแผนกที่มีอยู่เป็นอินสแตนซ์ของพนักงานใหม่โดยไม่ได้รับเอนทิตีของแผนกก่อนเพราะฉันไม่ต้องการเลือกคิวรีอื่นที่จะเริ่มทำงาน
ในบางสถานการณ์deptId
PKID มาnull
จากวิธีการโทรและฉันได้รับข้อผิดพลาดเดียวกัน
ดังนั้นดูnull
ค่า PK ID
ปัญหานี้เกิดขึ้นกับฉันเมื่อฉันสร้างเอนทิตีใหม่และนิติบุคคลที่เกี่ยวข้องในวิธีการทำเครื่องหมายเป็น@Transactional
จากนั้นดำเนินการแบบสอบถามก่อนบันทึก อดีต
@Transactional
public someService() {
Entity someEntity = new Entity();
AssocaiatedEntity associatedEntity = new AssocaitedEntity();
someEntity.setAssociatedEntity(associatedEntity);
associatedEntity.setEntity(someEntity);
// Performing any query was causing hibernate to attempt to persist the new entity. It would then throw an exception
someDao.getSomething();
entityDao.create(someEntity);
}
ในการแก้ไขฉันดำเนินการแบบสอบถามก่อนที่จะสร้างเอนทิตีใหม่
ข้างคำตอบที่ดีอื่น ๆ ทั้งหมดสิ่งนี้อาจเกิดขึ้นได้หากคุณใช้merge
เพื่อคงอยู่ของวัตถุและลืมที่จะใช้การอ้างอิงที่ผสานของวัตถุในคลาสแม่ พิจารณาตัวอย่างต่อไปนี้
merge(A);
B.setA(A);
persist(B);
ในกรณีนี้คุณผสานแต่ลืมที่จะใช้วัตถุที่ผสานของA
A
เพื่อแก้ปัญหาคุณต้องเขียนโค้ดเช่นนี้อีกครั้ง
A=merge(A);//difference is here
B.setA(A);
persist(B);
ฉันได้รับข้อผิดพลาดนี้เมื่อฉันใช้
getSession().save(object)
แต่มันทำงานได้อย่างไม่มีปัญหาเมื่อฉันใช้
getSession().saveOrUpdate(object)
ฉันยังต้องเผชิญกับสถานการณ์เดียวกัน ด้วยการตั้งค่าหมายเหตุประกอบต่อไปนี้ด้านบนคุณสมบัติทำให้แก้ไขข้อผิดพลาดที่แจ้งได้
ข้อยกเว้นที่ฉันเผชิญ
Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.model.Car_OneToMany
เพื่อเอาชนะคำอธิบายประกอบที่ฉันใช้
@OneToMany(cascade = {CascadeType.ALL})
@Column(name = "ListOfCarsDrivenByDriver")
private List<Car_OneToMany> listOfCarsBeingDriven = new ArrayList<Car_OneToMany>();
สิ่งที่ทำให้ไฮเบอร์เนตส่งข้อยกเว้น:
ข้อยกเว้นนี้ถูกส่งไปที่คอนโซลของคุณเนื่องจากวัตถุลูกที่ฉันแนบกับวัตถุแม่ไม่มีอยู่ในฐานข้อมูลในขณะนั้น
โดยการให้@OneToMany(cascade = {CascadeType.ALL})
มันบอก Hibernate เพื่อบันทึกลงในฐานข้อมูลในขณะที่บันทึกวัตถุแม่
เพื่อความสมบูรณ์: A
org.hibernate.TransientPropertyValueException
พร้อมข้อความ
object references an unsaved transient instance - save the transient instance before flushing
นอกจากนี้ยังจะเกิดขึ้นเมื่อคุณพยายามที่จะยังคงมีอยู่ / รวมกิจการกับการอ้างอิงไปยังหน่วยงานอื่นที่เกิดขึ้นจะถูกถอดออก
อีกสาเหตุหนึ่งที่เป็นไปได้: ในกรณีของฉันฉันพยายามบันทึกเด็กก่อนบันทึกผู้ปกครองบนเอนทิตีใหม่
รหัสคืออะไรเช่นนี้ในรูปแบบ User.java:
this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.setNewPassword(password);
this.timeJoin = new Date();
create();
เมธอด setNewPassword () สร้างเร็กคอร์ด PasswordHistory และเพิ่มลงในการรวบรวมประวัติใน User เนื่องจากคำสั่ง create () ยังไม่ได้ดำเนินการสำหรับผู้ปกครองมันจึงพยายามบันทึกลงในคอลเล็กชันของเอนทิตีที่ยังไม่ได้สร้างขึ้น สิ่งที่ฉันต้องทำเพื่อแก้ไขมันคือการย้ายการเรียก setNewPassword () หลังจากการโทรเพื่อสร้าง ()
this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.timeJoin = new Date();
create();
this.setNewPassword(password);
มีความเป็นไปได้อื่นที่อาจทำให้เกิดข้อผิดพลาดนี้ในโหมดไฮเบอร์เนต คุณอาจตั้งค่าการอ้างอิงวัตถุที่ไม่ได้บันทึกของคุณA
เป็นเอนทิตีที่แนบมาB
และต้องการคงวัตถุC
ไว้ แม้ในกรณีนี้คุณจะได้รับข้อผิดพลาดดังกล่าว
หากคุณกำลังใช้ Spring Data JPA การเพิ่ม@Transactional
หมายเหตุประกอบลงในการใช้บริการของคุณจะช่วยแก้ปัญหาได้
ฉันคิดว่าเป็นเพราะคุณพยายามคงวัตถุที่มีการอ้างอิงไปยังวัตถุอื่นที่ยังไม่ได้มีอยู่และดังนั้นจึงลองใน "ด้าน DB" เพื่อใส่การอ้างอิงไปยังแถวที่ไม่มีอยู่
วิธีง่ายๆในการแก้ไขปัญหานี้คือบันทึกเอนทิตีทั้งสอง ก่อนบันทึกเอนทิตีลูกแล้วบันทึกเอนทิตีหลัก เนื่องจากเอนทิตีหลักขึ้นอยู่กับเอนทิตีรองสำหรับค่าคีย์ต่างประเทศ
ด้านล่างการสอบง่าย ๆ ของความสัมพันธ์แบบหนึ่งต่อหนึ่ง
insert into Department (name, numOfemp, Depno) values (?, ?, ?)
Hibernate: insert into Employee (SSN, dep_Depno, firstName, lastName, middleName, empno) values (?, ?, ?, ?, ?, ?)
Session session=sf.openSession();
session.beginTransaction();
session.save(dep);
session.save(emp);
สาเหตุหนึ่งที่เป็นไปได้ของข้อผิดพลาดคือการไม่มีอยู่ของการตั้งค่าของเอนทิตีหลัก ตัวอย่างเช่นสำหรับความสัมพันธ์แผนกพนักงานคุณต้องเขียนสิ่งนี้เพื่อแก้ไขข้อผิดพลาด:
Department dept = (Department)session.load(Department.class, dept_code); // dept_code is from the jsp form which you get in the controller with @RequestParam String department
employee.setDepartment(dept);
มีความเป็นไปได้มากมายของข้อผิดพลาดนี้มีความเป็นไปได้อื่น ๆ เช่นกันในการเพิ่มหน้าหรือแก้ไขหน้า ในกรณีของฉันฉันพยายามบันทึกวัตถุ AdvanceSalary ปัญหาคือว่าในการแก้ไข AdvanceSalary employee.employee_id เป็นโมฆะเพราะในการแก้ไขฉันไม่ได้ตั้งค่า employee.employee_id ฉันสร้างฟิลด์ที่ซ่อนไว้และตั้งค่า รหัสของฉันทำงานได้ดีอย่างแน่นอน
@Entity(name = "ic_advance_salary")
@Table(name = "ic_advance_salary")
public class AdvanceSalary extends BaseDO{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "employee_id", nullable = false)
private Employee employee;
@Column(name = "employee_id", insertable=false, updatable=false)
@NotNull(message="Please enter employee Id")
private Long employee_id;
@Column(name = "advance_date")
@DateTimeFormat(pattern = "dd-MMM-yyyy")
@NotNull(message="Please enter advance date")
private Date advance_date;
@Column(name = "amount")
@NotNull(message="Please enter Paid Amount")
private Double amount;
@Column(name = "cheque_date")
@DateTimeFormat(pattern = "dd-MMM-yyyy")
private Date cheque_date;
@Column(name = "cheque_no")
private String cheque_no;
@Column(name = "remarks")
private String remarks;
public AdvanceSalary() {
}
public AdvanceSalary(Integer advance_salary_id) {
this.id = advance_salary_id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Long getEmployee_id() {
return employee_id;
}
public void setEmployee_id(Long employee_id) {
this.employee_id = employee_id;
}
}
ฉันประสบข้อยกเว้นนี้เมื่อฉันไม่ได้เก็บวัตถุแม่ แต่ฉันก็ช่วยเด็ก เพื่อแก้ไขปัญหาในเซสชั่นเดียวกันฉันยืนยันทั้งวัตถุลูกและวัตถุแม่และใช้ CascadeType.ALL บนแม่
กรณีที่ 1: ฉันได้รับข้อยกเว้นนี้เมื่อฉันพยายามสร้างพาเรนต์และบันทึกพาเรนต์อ้างอิงไปยังลูกของมันและจากนั้นแบบสอบถาม DELETE / UPDATE อื่น ๆ (JPQL) ดังนั้นฉันเพียงแค่ล้าง () เอนทิตีที่สร้างขึ้นใหม่หลังจากสร้างพาเรนต์และหลังจากสร้างเด็กโดยใช้การอ้างอิงพาเรนต์เดียวกัน มันใช้งานได้สำหรับฉัน
กรณีที่ 2:
ระดับผู้ปกครอง
public class Reference implements Serializable {
@Id
@Column(precision=20, scale=0)
private BigInteger id;
@Temporal(TemporalType.TIMESTAMP)
private Date modifiedOn;
@OneToOne(mappedBy="reference")
private ReferenceAdditionalDetails refAddDetails;
.
.
.
}
ชั้นเรียนเด็ก:
public class ReferenceAdditionalDetails implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@OneToOne
@JoinColumn(name="reference",referencedColumnName="id")
private Reference reference;
private String preferedSector1;
private String preferedSector2;
.
.
}
ในกรณีข้างต้นที่ผู้ปกครอง (อ้างอิง) และลูก (ReferenceAdditionalDetails) มีความสัมพันธ์ OneToOne และเมื่อคุณพยายามสร้างเอนทิตีอ้างอิงแล้วลูกของมัน (ReferenceAdditionalDetails) มันจะทำให้คุณมีข้อยกเว้นเดียวกัน ดังนั้นเพื่อหลีกเลี่ยงข้อยกเว้นคุณจะต้องตั้งค่า Null สำหรับคลาสย่อยแล้วสร้างพาเรนต์ (รหัสตัวอย่าง)
.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.
ปัญหาของฉันเกี่ยวข้องกับ@BeforeEach
JUnit และแม้ว่าฉันบันทึกหน่วยงานที่เกี่ยวข้อง (ในกรณีของฉัน@ManyToOne
) ฉันได้รับข้อผิดพลาดเดียวกัน
ปัญหาเกี่ยวข้องอย่างใดกับลำดับที่ฉันมีในแม่ของฉัน หากฉันกำหนดค่าให้กับแอตทริบิวต์นั้นปัญหาจะได้รับการแก้ไข
อดีต หากฉันมีคำถามเอนทิตีที่สามารถมีบางหมวดหมู่ (หนึ่งรายการขึ้นไป) และคำถามเอนทิตีมีลำดับ:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "feedbackSeq")
@Id
private Long id;
ฉันต้องกำหนดค่า question.setId(1L);
เพียงแค่สร้าง Constructor ของการแมปในคลาสพื้นฐานของคุณ เช่นถ้าคุณต้องการความสัมพันธ์แบบหนึ่งต่อหนึ่งใน Entity A, Entity B. ถ้าคุณใช้ A เป็นคลาสพื้นฐานดังนั้น A ต้องมี Constructor ที่มี B เป็นอาร์กิวเมนต์