Jak naprawić hibernację „obiekt odwołuje się do niezapisanej przejściowej instancji - zapisz przejściową instancję przed opróżnieniem”

609

Podczas zapisywania obiektu za pomocą Hibernacji pojawia się następujący błąd

object references an unsaved transient instance - save the transient instance before flushing
Tushar Ahirrao
źródło
1
Czy w kontekście braku jest ten błąd? czy jest ze zmienną przejściową czy bez?
vijay

Odpowiedzi:

801

Powinieneś dołączyć cascade="all"(jeśli używasz xml) lub cascade=CascadeType.ALL(jeśli używasz adnotacji) do swojego mapowania kolekcji.

Dzieje się tak, ponieważ masz kolekcję w swojej encji, a ta kolekcja zawiera jeden lub więcej elementów, które nie są obecne w bazie danych. Określając powyższe opcje, każesz hibernacji zapisać je w bazie danych podczas zapisywania ich elementu nadrzędnego.

Bozho
źródło
7
Czy to nie jest dorozumiane? Czy nie zawsze chciałbyś, aby Hibernacja je uratowała?
Marcus Leon
29
@Marcus - nie, nie jest. Możesz chcieć obsługiwać je ręcznie.
Bozho
5
Bozho ma rację. Napotkałem okoliczności, w których miałem kolekcje, którymi chciałem zarządzać ręcznie ze względu na ich rozmiar lub z powodu reguł biznesowych, które nie zezwalają na jednoczesne zapisywanie wszystkich obiektów w kolekcji.
Alex Marshall,
26
Nie dzieje się tak tylko w przypadku kolekcji, ale także prostych mapowań jeden na jeden
Sebastien Lorber
12
Czy nie lepiej byłoby zacząć od CascadeType.PERSIST i użyć opcji keep, aby zapisać?
Sergii Shevchyk
248

Wierzę, że to może być tylko powtórzenie odpowiedzi, ale dla wyjaśnienia, mam to na @OneToOnemapie, a także @OneToMany. W obu przypadkach był to fakt, że Childobiekt, który dodawałem, Parentnie był jeszcze zapisany w bazie danych. Więc kiedy dodałem Childdo Parent, a następnie zapisałem Parent, Hibernacja podrzuciłaby "object references an unsaved transient instance - save the transient instance before flushing"wiadomość podczas zapisywania Rodzica.

Dodanie w cascade = {CascadeType.ALL}sprawie Parent'sodniesienia do Childrozwiązania problemu w obu przypadkach. To uratowało Childi Parent.

Przepraszamy za powtarzające się odpowiedzi, chciałem tylko wyjaśnić ludziom.

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}
McDonald Noland
źródło
7
Co jeśli nie chcę kaskadowo zapisywać w relacji @OneToOne? Jak mogę utworzyć oba obiekty po raz pierwszy w bazie danych bez wyzwalania wyjątku?
xtian
4
Co jeśli chcę uratować dziecko w niektórych przypadkach, a nie w innych?
Omaruchan
@xtian: Więc musisz zadbać o właściwą kolejność zapisywania w bazie danych, utrwalając obiekty za pomocą EntityManager. W podstawowym po prostu mówisz em.persist (object1); em.persist (object2); itp.
kaba713,
Ten problem wystąpił konkretnie, gdy użyłem @Inheritance, w tym przypadku TABLE_PER_CLASS odwoływałem się do podklasy. CascadeType.ALL naprawił to.
Jim ReesPotter
Lub utworzyłeś obiekt encji za pomocą new MyEntity(bez synchronizacji z bazą danych - opróżnianie), zamiast pobierania jego zsynchronizowanej instancji z bazy danych. Wykonywanie zapytań Hibernacja przy użyciu tego wystąpienia informuje, że to, czego oczekujesz w bazie danych, różni się od tego, co masz w pamięci aplikacji. W takim przypadku - po prostu zsynchronizuj / pobierz instancję z DB i użyj jej. Wówczas CascadeType.ALL nie jest potrzebny.
Strefa
66

Dzieje się tak podczas zapisywania obiektu, gdy Hibernacja uważa, że ​​musi on zapisać obiekt skojarzony z tym, który zapisujesz.

Miałem ten problem i nie chciałem zapisywać zmian w przywoływanym obiekcie, więc chciałem, aby typ kaskady był BRAK.

Sztuczka polega na upewnieniu się, że identyfikator i WERSJA w przywoływanym obiekcie są ustawione, aby Hibernacja nie uważała, że ​​przywoływany obiekt jest nowym obiektem, który wymaga zapisania. To zadziałało dla mnie.

Przejrzyj wszystkie relacje w zapisywanej klasie, aby opracować powiązane obiekty (i powiązane obiekty powiązanych obiektów) i upewnij się, że ID i WERSJA są ustawione we wszystkich obiektach drzewa obiektów.

Cookalino
źródło
4
Ten komentarz postawił mnie na właściwej drodze. Przypisywałem nową instancję rodzica do właściwości jego dziecka. NH pomyślał, że to różne przypadki.
elvin
2
Tak. Dzieje się tak, jeśli na przykład identyfikator powiązanego obiektu nie jest uwzględniony (np. Został zignorowany przez @JsonIgnore). Hibernacja nie ma możliwości zidentyfikowania powiązanej jednostki, więc chce ją zapisać.
Rori Stumpf
36

Wprowadzenie

Jak wyjaśniłem w tym artykule podczas korzystania z JPA i Hibernacji, jednostka może znajdować się w jednym z następujących 4 stanów:

  • Nowość - Nowo utworzony obiekt, który nigdy nie był skojarzony z sesją hibernacji (inaczej Kontekst Persistence) i nie jest odwzorowany na żaden wiersz tabeli bazy danych, jest uważany za będący w stanie Nowy lub Przejściowy.

    Aby się utrwalić, musimy albo jawnie wywołać tę persistmetodę, albo skorzystać z mechanizmu trwałości przechodniego.

  • Trwały - trwały byt został powiązany z wierszem tabeli bazy danych i jest zarządzany przez aktualnie działający kontekst trwałości.

    Wszelkie zmiany dokonane w takiej jednostce zostaną wykryte i propagowane do bazy danych (podczas czasu opróżniania sesji).

  • Odłączony - Po zamknięciu aktualnie działającego kontekstu trwałości odłączane są wszystkie wcześniej zarządzane jednostki. Kolejne zmiany nie będą już śledzone i nie nastąpi automatyczna synchronizacja bazy danych.

  • Usunięte - chociaż JPA wymaga, aby usuwane były tylko zarządzane jednostki, Hibernacja może również usuwać odłączone jednostki (ale tylko poprzez removewywołanie metody).

Przejścia stanu encji

Aby przenieść jednostkę z jednego stanu do drugiego, można użyć persist, removeani mergemetod.

Stwierdza podmiot WZP

Naprawianie problemu

Problem, który opisujesz w swoim pytaniu:

object references an unsaved transient instance - save the transient instance before flushing

jest spowodowany przez powiązanie encji w stanie Nowy z encją w stanie Zarządzanym .

Może się to zdarzyć, gdy kojarzy się jednostkę podrzędną z kolekcją jeden do wielu w jednostce nadrzędnej, a kolekcja nie cascade stanu encji.

Tak więc, jak wyjaśniłem w tym artykule , możesz to naprawić, dodając kaskadę do powiązania encji, która spowodowała ten błąd, w następujący sposób:

@OneToOnestowarzyszenie

@OneToOne(
    mappedBy = "post",
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private PostDetails details;

Zwróć uwagę na CascadeType.ALLwartość, którą dodaliśmy dla cascadeatrybutu.

@OneToManystowarzyszenie

@OneToMany(
    mappedBy = "post", 
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();

Ponownie CascadeType.ALLnadaje się do skojarzeń dwukierunkowych@OneToMany .

Teraz, aby kaskada działała poprawnie w trybie dwukierunkowym, musisz także upewnić się, że skojarzenia nadrzędne i podrzędne są zsynchronizowane.

Sprawdź ten artykuł, aby uzyskać więcej informacji na temat najlepszego sposobu osiągnięcia tego celu.

@ManyToManystowarzyszenie

@ManyToMany(
    mappedBy = "authors",
    cascade = {
        CascadeType.PERSIST, 
        CascadeType.MERGE
    }
)
private List<Book> books = new ArrayList<>();

W @ManyToManyzwiązku nie można używać CascadeType.ALLluborphanRemoval ponieważ spowoduje to propagację przejścia stanu usuwania encji z jednego rodzica na inny podmiot nadrzędny.

Dlatego w przypadku @ManyToManyskojarzeń zwykle kaskadowo wykonuje się operacje CascadeType.PERSISTlub CascadeType.MERGE. Alternatywnie możesz rozwinąć to do DETACHlub REFRESH.

Aby uzyskać więcej informacji na temat najlepszego sposobu mapowania @ManyToManypowiązania, sprawdź również ten artykuł .

Vlad Mihalcea
źródło
Pełne i spójne wyjaśnienie! Dobra robota!
Zimny
Możesz znaleźć setki takich szczegółowych wyjaśnień w moim samouczku Hibernacji .
Vlad Mihalcea
30

Lub, jeśli chcesz użyć minimalnych „mocy” (np. Jeśli nie chcesz kasować kasowania), aby osiągnąć to, czego chcesz, użyj

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

...

@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;
Haris Osmanagić
źródło
11
To powinna być zaakceptowana odpowiedź. CascadeType.ALL jest zbyt szeroki
lilalinux
5
Począwszy od wersji Hibernacji 5.2.8 wydaje się, że nie można osiągnąć tego samego efektu za pomocą adnotacji JPA. Na przykład @ManyToMany(cascade={PERSIST, MERGE, REFRESH, DETACH})(wszystkie oprócz USUŃ) nie kaskadują aktualizacji, jak Hibernacja CascadeType.SAVE_UPDATE.
jcsahnwaldt mówi GoFundMonica
25

W moim przypadku było to spowodowane nie mając CascadeTypena @ManyToOnestronie relacji dwukierunkowej. Mówiąc ściślej, miałem CascadeType.ALLpo @OneToManystronie i nie miałem go na sobie @ManyToOne. Dodawanie w CascadeType.ALLcelu @ManyToOnerozwiązania problemu. Strona jeden do wielu :

@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;

Strona wiele do jednego (spowodowała problem)

@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;

Wiele do jednego (naprawione przez dodanie CascadeType.PERSIST)

@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
allap
źródło
Jeśli zrobię to w ten sposób i zapiszę jednostkę nadrzędną, dzieje się tak, że w mojej tabeli nadrzędnej są dwie wstawki, czyli dwa wiersze. Myślę, że to dlatego, że mamy kaskadę na jednostkach nadrzędnych i podrzędnych?
theprogrammer
18

Stało się to dla mnie, gdy trwałem bytu, w którym istniejący rekord w bazie danych miał wartość NULL dla pola z adnotacją @Version (dla optymistycznego blokowania). Poprawiono wartość NULL do 0 w bazie danych.

dukethrash
źródło
To powinno być nowe pytanie i powinno zostać dodane jako błąd, przynajmniej wprowadzający w błąd wyjątek. To okazało się przyczyną mojego problemu.
BML
To rozwiązuje mój problem
Jad Chahine
11

To nie jedyny powód błędu. Spotkałem go właśnie teraz z powodu błędu literowego w moim kodzie, który, jak sądzę, ustawił wartość bytu, który został już zapisany.

X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);

Zauważyłem błąd, znajdując dokładnie, która zmienna spowodowała błąd (w tym przypadku String xid). Użyłem catchcałego bloku kodu, który uratował byt i wydrukował ślady.

{
   code block that performed the operation
} catch (Exception e) {
   e.printStackTrace(); // put a break-point here and inspect the 'e'
   return ERROR;
}
nanospeck
źródło
1
Podobny problem do mojego. W końcu, kiedy ponownie załadowałem jednostkę lokalnie, ustawiłem właściwość, a następnie zapisałem, działała dobrze.
CsBalazsHungary
8

Nie używaj, Cascade.Alldopóki naprawdę nie musisz. Rolei Permissionmają manyToManyrelacje dwukierunkowe . Następnie następujący kod będzie działał poprawnie

    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);

podczas gdy jeśli obiekt jest po prostu „nowy”, wygenerowałby ten sam błąd.

Tiina
źródło
1
jest w 100% poprawny, Cascade. Wszystko jest leniwym rozwiązaniem i powinno być stosowane tylko w razie potrzeby. po pierwsze, jeśli jednostka już istnieje, sprawdź, czy jest załadowana do bieżącego menedżera encji, jeśli nie, załaduj ją.
Renato Mendes,
7

Jeśli twoja kolekcja ma wartość zerową, po prostu spróbuj: object.SetYouColection(null);

Joabe Lucena
źródło
To był całkowicie mój problem. Nigdy bym nie przypuszczał, że musiałem ręcznie ustawić na zero.
Deadron,
To był również mój problem. Nie używałem kolekcji, więc nie próbowałem tego na początku, ale ustawiłem mój obiekt na zero, a teraz działa.
Fodder
5

Aby dodać moje 2 centy, dostałem ten sam problem, gdy przypadkowo wysyłam nulljako identyfikator. Poniższy kod przedstawia mój scenariusz (a OP nie wspomniał o żadnym konkretnym scenariuszu) .

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);

Tutaj ustawiam istniejący identyfikator działu na nową instancję pracownika, nie pobierając najpierw jednostki działu, ponieważ nie chcę uruchamiać innego wybranego zapytania.

W niektórych scenariuszach deptIdPKID pochodzi nullod metody wywołania i otrzymuję ten sam błąd.

Uważaj więc na nullwartości dla PK ID

manikanta
źródło
co jeśli to nullable?
vipin cp
Mam podobny problem. Otrzymuję wyjątek, gdy mój deptID wynosi 0. Każda inna wartość większa niż 0 działa. Zabawne, że mam dept o id = 0.
Gustavo
5

Ten problem przydarzył mi się, gdy utworzyłem nowy obiekt i powiązany obiekt w metodzie oznaczonej jako @Transactional, a następnie wykonałem zapytanie przed zapisaniem. Dawny

@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);
}

Aby to naprawić, wykonałem zapytanie przed utworzeniem nowego obiektu.

mad_fox
źródło
4

oprócz wszystkich innych dobrych odpowiedzi, może się tak zdarzyć, jeśli użyjesz mergedo utrwalenia obiektu i przypadkowo zapomnisz użyć scalonego odwołania do obiektu w klasie nadrzędnej. rozważ następujący przykład

merge(A);
B.setA(A);
persist(B);

W takim przypadku scalasz, Aale zapominasz użyć scalonego obiektu A. aby rozwiązać problem, musisz przepisać kod w ten sposób.

A=merge(A);//difference is here
B.setA(A);
persist(B);
Hossein Nasr
źródło
3

pojawia się ten błąd, gdy korzystam

getSession().save(object)

ale działa bez problemu, gdy używam

getSession().saveOrUpdate(object) 
acpuma
źródło
3

Też spotkałem się z tą samą sytuacją. Ustawienie poniższej adnotacji nad właściwością sprawiło, że rozwiązano zgłoszony wyjątek.

Wyjątek, z którym się spotkałem.

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

Aby przezwyciężyć, użyłem adnotacji.

    @OneToMany(cascade = {CascadeType.ALL})
    @Column(name = "ListOfCarsDrivenByDriver")
    private List<Car_OneToMany> listOfCarsBeingDriven = new ArrayList<Car_OneToMany>();

Co sprawiło, że Hibernacja rzuciła wyjątek:

Ten wyjątek jest zgłaszany do konsoli, ponieważ obiekt podrzędny, który dołączam do obiektu nadrzędnego, nie jest w tym momencie obecny w bazie danych.

Podając @OneToMany(cascade = {CascadeType.ALL}), informuje Hibernację, aby zapisał je w bazie danych podczas zapisywania obiektu nadrzędnego.

Dulith De Costa
źródło
2

Dla kompletności: A

org.hibernate.TransientPropertyValueException 

z wiadomością

object references an unsaved transient instance - save the transient instance before flushing

pojawi się również, gdy spróbujesz utrwalić / scalić byt z odniesieniem do innego bytu, który przypadkowo zostanie odłączony .

Ralf
źródło
1

Jeszcze jeden możliwy powód: w moim przypadku próbowałem uratować dziecko przed uratowaniem rodzica, na zupełnie nowej jednostce.

Kod wyglądał mniej więcej tak w modelu User.java:

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.setNewPassword(password);
this.timeJoin = new Date();
create();

Metoda setNewPassword () tworzy rekord PasswordHistory i dodaje go do kolekcji historii w User. Ponieważ instrukcja create () nie została jeszcze wykonana dla elementu nadrzędnego, próbowała zapisać w kolekcji encji, która nie została jeszcze utworzona. Wszystko, co musiałem zrobić, aby to naprawić, to przenieść wywołanie setNewPassword () po wywołaniu create ().

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.timeJoin = new Date();
create();
this.setNewPassword(password);
Jeremy Goodell
źródło
1

Istnieje inna możliwość, która może spowodować ten błąd w trybie hibernacji. Możesz ustawić niezapisane odniesienie swojego obiektu Ado dołączonej encji Bi chcesz utrwalić obiekt C. Nawet w tym przypadku otrzymasz wyżej wymieniony błąd.

Hossein Nasr
źródło
1

Jeśli używasz JPA Spring Data, dodanie @Transactionaladnotacji do implementacji usługi rozwiązałoby problem.

Usama
źródło
1

Myślę, że dzieje się tak, ponieważ próbujesz utrwalić obiekt, który ma odwołanie do innego obiektu, który nie jest jeszcze trwały, i dlatego po stronie DB próbuje umieścić odniesienie do wiersza, który nie istnieje


źródło
0

Prostym sposobem rozwiązania tego problemu jest uratowanie obu podmiotów. najpierw zapisz element potomny, a następnie zapisz element macierzysty. Ponieważ jednostka nadrzędna jest zależna od jednostki podrzędnej dla wartości klucza obcego.

Poniżej prosty egzamin relacji jeden do jednego

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);
shashigura
źródło
1
Przeciwnie - jednostka potomna posiada wartość FK i zależy od rodzica, więc najpierw musisz zapisać rodzica! W bloku kodu masz rację.
Sõber
0

Jedną z możliwych przyczyn błędu jest nieistnienie ustawienia wartości jednostki dominującej; na przykład dla relacji dział-pracownik musisz to napisać, aby naprawić błąd:

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);
feromix
źródło
0

Jest tak wiele możliwości tego błędu, że inne możliwości znajdują się również na stronie dodawania lub edycji strony. W moim przypadku próbowałem zapisać obiekt AdvanceSalary. Problem polega na tym, że w edycji AdvanceSalary pracownik.employee_id ma wartość NULL, ponieważ podczas edycji nie ustawiłem pracownika.employee_id. Zrobiłem ukryte pole i ustawiłem je. mój kod działa absolutnie dobrze.

    @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;
        }

    }
Ravindra
źródło
0

Spotykałem się z tym wyjątkiem, gdy nie utrwalałem obiektu nadrzędnego, ale zapisywałem dziecko. Aby rozwiązać problem, w tej samej sesji utrwaliłem zarówno obiekty podrzędne, jak i nadrzędne i użyłem CascadeType.ALL na rodzicu.

Tadele Ayelegn
źródło
0

Przypadek 1: Otrzymałem ten wyjątek, gdy próbowałem utworzyć element nadrzędny i zapisać to odwołanie elementu nadrzędnego do jego elementu podrzędnego, a następnie inne zapytanie DELETE / UPDATE (JPQL). Więc po prostu opróżniam () nowo utworzony byt po utworzeniu elementu nadrzędnego i po utworzeniu elementu podrzędnego przy użyciu tego samego odwołania nadrzędnego. To zadziałało dla mnie.

Przypadek 2:

Klasa rodzicielska

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;
    . 
    .
    .
}

Klasa dla dzieci:

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;
    .
    .

}

W powyższym przypadku, gdy rodzic (Reference) i child (ReferenceAdditionalDetails) mają relację OneToOne, a gdy spróbujesz utworzyć obiekt Reference, a następnie jego obiekt potomny (ReferenceAdditionalDetails), otrzymasz ten sam wyjątek. Aby uniknąć wyjątku, musisz ustawić wartość null dla klasy potomnej, a następnie utworzyć element nadrzędny. (Przykładowy kod)

.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.
Harsh Vardhan Singh Solanki
źródło
0

Mój problem dotyczył @BeforeEachJUnit. I nawet jeśli zapisałem powiązane podmioty (w moim przypadku@ManyToOne ), dostałem ten sam błąd.

Problem jest w jakiś sposób związany z sekwencją, którą mam u rodzica. Jeśli przypiszę wartość do tego atrybutu, problem zostanie rozwiązany.

Dawny. Jeśli mam pytanie encji, które może mieć pewne kategorie (jedną lub więcej), a pytanie encji ma sekwencję:

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "feedbackSeq")
@Id
private Long id;

Muszę przypisać wartość question.setId(1L);

NikNik
źródło
0

Po prostu uczyń Konstruktorem swojego mapowania w swojej klasie podstawowej. Na przykład, jeśli chcesz relacji jeden-do-jednego w Podmiocie A, Podmiotu B., jeśli bierzesz A jako klasę podstawową, to A musi mieć Konstruktor jako argument B.

Bilal Ahmad
źródło