So beheben Sie den Fehler im Ruhezustand: "Objekt verweist auf eine nicht gespeicherte vorübergehende Instanz - Speichern Sie die vorübergehende Instanz vor dem Löschen"


610

Beim Speichern des Objekts im Ruhezustand wird folgende Fehlermeldung angezeigt

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

1
Im Suchkontext ist dieser Fehler? ist es mit oder ohne transiente Variable?
Vijay

Antworten:


803

Sie sollten cascade="all"(wenn Sie XML verwenden) oder cascade=CascadeType.ALL(wenn Sie Anmerkungen verwenden) in Ihre Sammlungszuordnung aufnehmen.

Dies liegt daran, dass Sie eine Sammlung in Ihrer Entität haben und diese Sammlung ein oder mehrere Elemente enthält, die nicht in der Datenbank vorhanden sind. Indem Sie die oben genannten Optionen angeben, weisen Sie den Ruhezustand an, sie beim Speichern des übergeordneten Elements in der Datenbank zu speichern.


7
Ist das nicht implizit? Möchten Sie nicht immer, dass der Ruhezustand sie rettet?
Marcus Leon

29
@Marcus - nein, das ist es nicht. Möglicherweise möchten Sie sie manuell behandeln.
Bozho

5
Bozho hat recht. Ich bin auf Umstände gestoßen, in denen ich Sammlungen hatte, die ich aufgrund ihrer Größe manuell verwalten wollte, oder aufgrund von Geschäftsregeln, nach denen nicht alle Objekte in einer Sammlung gleichzeitig gespeichert werden können.
Alex Marshall

26
Es passiert nicht nur für Sammlungen, sondern auch für einfache Eins-zu-Eins-Zuordnungen
Sebastien Lorber

12
Wäre es nicht besser, mit CascadeType.PERSIST zu beginnen und persist zum Speichern zu verwenden?
Sergii Shevchyk

248

Ich glaube, dies könnte nur eine wiederholte Antwort sein, aber nur um dies zu verdeutlichen, habe ich dies sowohl auf einem @OneToOneMapping als auch auf einem @OneToMany. In beiden Fällen war es die Tatsache, dass das ChildObjekt , das ich hinzugefügt habe, Parentnoch nicht in der Datenbank gespeichert war. Wenn ich also das Childzum hinzufügte Parentund dann das speicherte Parent, warf Hibernate die "object references an unsaved transient instance - save the transient instance before flushing"Nachricht beim Speichern des übergeordneten Elements.

Das Hinzufügen cascade = {CascadeType.ALL}des Parent'sVerweises auf Childdas Problem wurde in beiden Fällen gelöst. Dies rettete das Childund das Parent.

Entschuldigen Sie die wiederholten Antworten, ich wollte sie nur weiter klären.

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}

7
Was ist, wenn ich keine @ OneToOne-Beziehung kaskadieren möchte? Wie kann ich beim erstmaligen Erstellen beider Objekte eines in der Datenbank speichern, ohne die Ausnahme auszulösen?
Xtian

4
Was ist, wenn ich das Kind für einige Fälle und nicht für andere retten möchte?
Omaruchan

@xtian: Nun, dann müssen Sie sich um die richtige Reihenfolge beim Speichern in der Datenbank kümmern, indem Sie die Objekte mit einem EntityManager beibehalten. Im Grunde sagen Sie einfach em.persist (object1); em.persist (object2); usw.
kaba713

Ich habe dieses Problem speziell bei der Verwendung von @Inheritance erhalten. In diesem Fall hat TABLE_PER_CLASS auf eine Unterklasse verwiesen. CascadeType.ALL hat das Problem behoben.
Jim ReesPotter

Oder Sie haben Ihr Entitätsobjekt mit erstellt new MyEntity(ohne es mit der Datenbank zu synchronisieren - Leeren), anstatt seine synchronisierte Instanz aus der Datenbank abzurufen. Wenn Sie mit dieser Instanz Abfragen im Ruhezustand durchführen, werden Sie darüber informiert, dass sich das, was Sie in der Datenbank erwarten, von dem unterscheidet, was Sie im Speicher Ihrer App haben. In diesem Fall - synchronisieren Sie einfach Ihre Entitätsinstanz aus der Datenbank und verwenden Sie sie. Dann wird kein CascadeType.ALL benötigt.
Zon

67

Dies geschieht beim Speichern eines Objekts, wenn Hibernate der Ansicht ist, dass ein Objekt gespeichert werden muss, das dem Objekt zugeordnet ist, das Sie speichern.

Ich hatte dieses Problem und wollte keine Änderungen am referenzierten Objekt speichern, daher wollte ich, dass der Kaskadentyp NONE ist.

Der Trick besteht darin, sicherzustellen, dass ID und VERSION im referenzierten Objekt so festgelegt sind, dass Hibernate nicht glaubt, dass das referenzierte Objekt ein neues Objekt ist, das gespeichert werden muss. Das hat bei mir funktioniert.

Durchsuchen Sie alle Beziehungen in der Klasse, die Sie speichern, um die zugeordneten Objekte (und die zugeordneten Objekte der zugeordneten Objekte) zu ermitteln, und stellen Sie sicher, dass ID und VERSION in allen Objekten des Objektbaums festgelegt sind.


4
Dieser Kommentar hat mich auf den richtigen Weg gebracht. Ich habe eine neue Instanz des Elternteils einer Eigenschaft seines Kindes zugewiesen. Also dachte NH, es seien verschiedene Fälle.
Elvin

2
Ja. Dies geschieht beispielsweise, wenn die ID des zugeordneten Objekts nicht enthalten ist (z. B. wurde sie von @JsonIgnore ignoriert). Der Ruhezustand hat keine Möglichkeit, die zugeordnete Entität zu identifizieren, daher möchte er sie speichern.
Rori Stumpf

36

Einführung

Wie ich in diesem Artikel bei Verwendung von JPA und Hibernate erläutert habe , kann sich eine Entität in einem der folgenden 4 Zustände befinden:

  • Neu - Ein neu erstelltes Objekt, das noch nie einer Ruhezustandssitzung (auch als Persistenzkontext bezeichnet) zugeordnet wurde und keiner Datenbanktabellenzeile zugeordnet ist, befindet sich im Status Neu oder Transient.

    Um persistent zu werden, müssen wir entweder die persistMethode explizit aufrufen oder den transitiven Persistenzmechanismus verwenden.

  • Persistent - Eine persistente Entität wurde einer Datenbanktabellenzeile zugeordnet und wird vom aktuell ausgeführten Persistenzkontext verwaltet.

    Jede an einer solchen Entität vorgenommene Änderung wird erkannt und an die Datenbank weitergegeben (während der Sitzungsspülzeit).

  • Getrennt - Sobald der aktuell ausgeführte Persistenzkontext geschlossen ist, werden alle zuvor verwalteten Entitäten getrennt. Aufeinanderfolgende Änderungen werden nicht mehr verfolgt und es findet keine automatische Datenbanksynchronisierung statt.

  • Entfernt - Obwohl JPA verlangt, dass nur verwaltete Entitäten entfernt werden dürfen, kann Hibernate auch getrennte Entitäten löschen (jedoch nur über einen removeMethodenaufruf).

Übergänge des Entitätsstatus

Um ein Objekt von einem Zustand in den anderen zu bewegen, können Sie die verwenden persist, removeoder mergeMethoden.

JPA-Entitätszustände

Problem beheben

Das Problem, das Sie in Ihrer Frage beschreiben:

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

wird verursacht, indem eine Entität im Status Neu einer Entität zugeordnet wird, die sich im Status Verwaltet befindet .

Dies kann passieren, wenn Sie eine untergeordnete Entität einer Eins-zu-Viele-Sammlung in der übergeordneten Entität zuordnen und die Sammlung keine cascadeÜbergänge des Entitätsstatus ausführt.

Wie ich in diesem Artikel erklärt habe , können Sie dies beheben, indem Sie der Entitätszuordnung, die diesen Fehler ausgelöst hat, wie folgt eine Kaskade hinzufügen:

Der @OneToOneVerein

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

Beachten Sie den CascadeType.ALLWert, den wir für das cascadeAttribut hinzugefügt haben.

Der @OneToManyVerein

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

Auch hier CascadeType.ALList das für die bidirektionalen@OneToMany Assoziationen geeignet .

Damit die Kaskade nun bidirektional ordnungsgemäß funktioniert, müssen Sie außerdem sicherstellen, dass die übergeordneten und untergeordneten Zuordnungen synchron sind.

In diesem Artikel erfahren Sie mehr darüber, wie Sie dieses Ziel am besten erreichen können.

Der @ManyToManyVerein

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

In einer @ManyToManyZuordnung können Sie den Übergang des Löschentitätsstatus von einer übergeordneten zu einer anderen übergeordneten Entität nicht verwenden CascadeType.ALLoder übertragen orphanRemoval.

Daher @ManyToManykaskadieren Sie für Assoziationen normalerweise die Operationen CascadeType.PERSISToder CascadeType.MERGE. Alternativ können Sie das auf DETACHoder erweitern REFRESH.

Weitere Informationen zum besten Zuordnen einer @ManyToManyZuordnung finden Sie auch in diesem Artikel .


Vollständige und konsistente Erklärung! Gute Arbeit!
Kalt

Hunderte solcher detaillierten Erklärungen finden Sie in meinem Tutorial zum Ruhezustand .
Vlad Mihalcea

30

Oder wenn Sie minimale "Kräfte" verwenden möchten (z. B. wenn Sie keine Kaskadenlöschung wünschen), um das zu erreichen, was Sie wollen, verwenden Sie

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

...

@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;

11
Dies sollte die akzeptierte Antwort sein. CascadeType.ALL ist zu breit
Lilalinux

5
Ab Hibernate 5.2.8 scheint es keine Möglichkeit zu geben, mit JPA-Annotationen den gleichen Effekt zu erzielen. Zum Beispiel @ManyToMany(cascade={PERSIST, MERGE, REFRESH, DETACH})kaskadiert (alle außer REMOVE) keine Updates wie bei Hibernate CascadeType.SAVE_UPDATE.
Jcsahnwaldt sagt GoFundMonica

25

In meinem Fall wurde es dadurch verursacht, dass ich nicht CascadeTypeauf der @ManyToOneSeite der bidirektionalen Beziehung stand. Genauer gesagt hatte ich CascadeType.ALLauf der @OneToManySeite und hatte es nicht an @ManyToOne. Hinzufügen CascadeType.ALLzu@ManyToOne um das Problem beheben. Eins-zu-viele- Seite:

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

Viele-zu-eins-Seite (verursachte das Problem)

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

Viele zu eins (durch Hinzufügen behoben CascadeType.PERSIST)

@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;

Wenn ich es auf diese Weise mache und die übergeordnete Entität speichere, befinden sich in meiner übergeordneten Tabelle zwei Einfügungen, die zwei Zeilen umfassen. Ich denke, es liegt daran, dass wir sowohl übergeordnete als auch untergeordnete Entitäten kaskadieren?
Programmierer

18

Dies trat bei mir auf, als eine Entität beibehalten wurde, in der der vorhandene Datensatz in der Datenbank einen NULL-Wert für das mit @Version annotierte Feld hatte (für optimistisches Sperren). Das Aktualisieren des NULL-Werts auf 0 in der Datenbank hat dies korrigiert.


Dies sollte eine neue Frage sein und als Fehler hinzugefügt werden, zumindest als irreführende Ausnahme. Dies stellte sich als Ursache für mein Problem heraus.
BML

Dies behebt mein Problem
Jad Chahine

11

Dies ist nicht der einzige Grund für den Fehler. Ich bin gerade auf einen Tippfehler in meiner Codierung gestoßen, bei dem meiner Meinung nach ein Wert für eine Entität festgelegt wurde, die bereits gespeichert wurde.

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

Ich habe den Fehler entdeckt, indem ich genau herausgefunden habe, welche Variable den Fehler verursacht hat (in diesem Fall String xid). Ich habe einen catchCodeblock verwendet, der die Entität gespeichert und die Spuren gedruckt hat.

{
   code block that performed the operation
} catch (Exception e) {
   e.printStackTrace(); // put a break-point here and inspect the 'e'
   return ERROR;
}

1
Ähnliches Problem wie bei mir. Nachdem ich die Entität lokal neu geladen, die Eigenschaft festgelegt und dann gespeichert hatte, funktionierte sie einwandfrei.
CsBalazsHungary

8

Nicht verwenden, Cascade.Allbis Sie wirklich müssen. Roleund Permissionhaben bidirektionale manyToManyBeziehung. Dann würde der folgende Code gut funktionieren

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

Wenn das Objekt nur ein "neues" Objekt ist, wird derselbe Fehler ausgegeben.


1
Ist 100% korrekt, ist die Cascade.All die faule Lösung und sollte nur bei Bedarf angewendet werden. Wenn die Entität bereits vorhanden ist, überprüfen Sie zunächst, ob sie im aktuellen Entitätsmanager geladen ist. Wenn nicht, laden Sie sie.
Renato Mendes

7

Wenn Ihre Sammlung nullbar ist, versuchen Sie einfach: object.SetYouColection(null);


Das war total mein Problem. Ich hätte nie gedacht, dass ich es manuell auf null setzen muss.
Deadron

Dies war auch mein Problem. Ich habe keine Sammlung verwendet, also habe ich dies zuerst nicht versucht, aber ich habe mein Objekt auf null gesetzt und jetzt funktioniert es.
Futter

5

Um meine 2 Cent hinzuzufügen, habe ich das gleiche Problem, wenn ich versehentlich nullals ID sende . Der folgende Code zeigt mein Szenario (und OP hat kein bestimmtes Szenario erwähnt) .

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

Hier setze ich die vorhandene Abteilungs-ID auf eine neue Mitarbeiterinstanz, ohne zuerst die Abteilungsentität zu erhalten, da ich nicht möchte, dass eine andere ausgewählte Abfrage ausgelöst wird.

In einigen Szenarien kommt deptIdPKID alsnull von der aufrufenden Methode und ich den gleichen Fehler.

Achten Sie also auf nullWerte für die PK-ID


Was ist, wenn es nullbar ist?
Vipin CP

Ich habe ein ähnliches Problem. Ich erhalte die Ausnahme, wenn meine deptID 0 ist. Jeder andere Wert größer als 0 funktioniert. Komisch ist, dass ich eine Abteilung mit id = 0 habe.
Gustavo

5

Dieses Problem trat mir auf, als ich eine neue Entität und eine zugehörige Entität in einer als gekennzeichneten Methode erstellte und @Transactionalvor dem Speichern eine Abfrage durchführte. Ex

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

Um dies zu beheben, habe ich die Abfrage durchgeführt, bevor ich die neue Entität erstellt habe.


4

Neben allen anderen guten Antworten kann dies passieren, wenn Sie mergeein Objekt beibehalten und versehentlich vergessen, die zusammengeführte Referenz des Objekts in der übergeordneten Klasse zu verwenden. Betrachten Sie das folgende Beispiel

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

In diesem Fall führen Sie zusammen A, vergessen jedoch, das zusammengeführte Objekt von zu verwenden A. Um das Problem zu lösen, müssen Sie den Code wie folgt umschreiben.

A=merge(A);//difference is here
B.setA(A);
persist(B);

3

Ich bekomme diesen Fehler, wenn ich benutze

getSession().save(object)

aber es funktioniert ohne problem, wenn ich benutze

getSession().saveOrUpdate(object) 

3

Ich war auch mit der gleichen Situation konfrontiert. Durch Setzen der folgenden Anmerkung über der Eigenschaft wurde die angeforderte Ausnahme behoben.

Die Ausnahme, mit der ich konfrontiert war.

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

Um zu überwinden, die Anmerkung, die ich verwendet habe.

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

Was hat Hibernate dazu gebracht, die Ausnahme zu werfen:

Diese Ausnahme wird an Ihrer Konsole ausgelöst, da das untergeordnete Objekt, das ich an das übergeordnete Objekt anhänge, derzeit nicht in der Datenbank vorhanden ist.

Durch die Bereitstellung @OneToMany(cascade = {CascadeType.ALL})wird Hibernate angewiesen, sie in der Datenbank zu speichern, während das übergeordnete Objekt gespeichert wird.


2

Der Vollständigkeit halber: A.

org.hibernate.TransientPropertyValueException 

mit Nachricht

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

auftreten wird auch , wenn Sie versuchen , eine Einheit mit einem Verweis auf ein anderes Unternehmen zu beharren / fusionieren , die sich zufällig abgelöst .


1

Ein weiterer möglicher Grund: In meinem Fall habe ich versucht, das Kind vor dem Speichern des Elternteils auf einer brandneuen Entität zu retten.

Der Code war in einem User.java-Modell ungefähr so:

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

Die Methode setNewPassword () erstellt einen PasswordHistory-Datensatz und fügt ihn der Verlaufssammlung in User hinzu. Da die Anweisung create () für das übergeordnete Element noch nicht ausgeführt wurde, wurde versucht, sie in einer Sammlung einer Entität zu speichern, die noch nicht erstellt wurde. Alles, was ich tun musste, um das Problem zu beheben, war, den Aufruf von setNewPassword () nach dem Aufruf von create () zu verschieben.

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

1

Es gibt eine andere Möglichkeit, die diesen Fehler im Ruhezustand verursachen kann. Möglicherweise legen Sie einen nicht gespeicherten Verweis Ihres Objekts Aauf eine angehängte Entität fest Bund möchten das Objekt beibehalten C. Auch in diesem Fall erhalten Sie den oben genannten Fehler.


1

Wenn Sie Spring Data JPA verwenden @Transactional, wird das Problem durch Hinzufügen von Anmerkungen zu Ihrer Service-Implementierung behoben.


1

Ich denke, das liegt daran, dass Sie versucht haben, ein Objekt zu persistieren, das einen Verweis auf ein anderes Objekt hat, das noch nicht persistiert ist, und deshalb auf der "DB-Seite" versuchen, einen Verweis auf eine Zeile zu setzen, die nicht existiert


0

Eine einfache Möglichkeit, dieses Problem zu lösen, besteht darin, beide Entitäten zu speichern. Speichern Sie zuerst die untergeordnete Entität und dann die übergeordnete Entität. Da die übergeordnete Entität für den Fremdschlüsselwert von der untergeordneten Entität abhängt.

Unten einfache Prüfung einer Eins-zu-Eins-Beziehung

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

1
Es ist das Gegenteil - die untergeordnete Entität enthält den FK-Wert und hängt vom übergeordneten Element ab. Sie müssen also zuerst das übergeordnete Element speichern! Im Codeblock haben Sie es richtig.
17.

0

Eine mögliche Fehlerursache ist das Nichtvorhandensein der Einstellung des Werts der übergeordneten Entität. Für eine Beziehung zwischen Abteilung und Mitarbeitern müssen Sie dies beispielsweise schreiben, um den Fehler zu beheben:

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

0

Es gibt so viele Möglichkeiten für diesen Fehler. Einige andere Möglichkeiten gibt es auch auf Seite hinzufügen oder Seite bearbeiten. In meinem Fall habe ich versucht, ein Objekt AdvanceSalary zu speichern. Das Problem ist, dass beim Bearbeiten die AdvanceSalary employee.employee_id null ist. Da ich beim Bearbeiten die employee.employee_id nicht festgelegt habe. Ich habe ein verstecktes Feld gemacht und es gesetzt. Mein Code funktioniert absolut gut.

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

    }

0

Ich war mit dieser Ausnahme konfrontiert, als ich das übergeordnete Objekt nicht beibehalten habe, aber das Kind gerettet habe. Um das Problem zu beheben, habe ich in derselben Sitzung sowohl das untergeordnete als auch das übergeordnete Objekt beibehalten und CascadeType.ALL für das übergeordnete Objekt verwendet.


0

Fall 1: Ich habe diese Ausnahme erhalten, als ich versucht habe, ein übergeordnetes Element zu erstellen und diesen übergeordneten Verweis auf sein untergeordnetes Element und dann eine andere DELETE / UPDATE-Abfrage (JPQL) zu speichern. Ich spüle () einfach die neu erstellte Entität nach dem Erstellen des übergeordneten Elements und nach dem Erstellen des untergeordneten Elements unter Verwendung derselben übergeordneten Referenz. Es hat bei mir funktioniert.

Fall 2:

Übergeordnete Klasse

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

Kinderklasse:

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

}

In dem obigen Fall, in dem Eltern (Referenz) und Kind (ReferenzAdditionalDetails) eine OneToOne-Beziehung haben und wenn Sie versuchen, eine Referenzentität und dann ihr Kind (ReferenzAdditionalDetails) zu erstellen, erhalten Sie dieselbe Ausnahme. Um die Ausnahme zu vermeiden, müssen Sie für die untergeordnete Klasse null setzen und dann die übergeordnete Klasse erstellen. (Beispielcode)

.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.

0

Mein Problem @BeforeEachhing mit JUnit zusammen. Und selbst wenn ich die zugehörigen Entitäten gespeichert habe (in meinem Fall@ManyToOne ) , habe ich den gleichen Fehler erhalten.

Das Problem hängt irgendwie mit der Sequenz zusammen, die ich in meinem Elternteil habe. Wenn ich diesem Attribut den Wert zuordne, ist das Problem gelöst.

Ex. Wenn ich die Entitätsfrage habe, die einige Kategorien (eine oder mehrere) haben kann, und die Entitätsfrage eine Sequenz hat:

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

Ich muss den Wert zuweisen question.setId(1L);


0

Machen Sie einfach den Konstruktor Ihres Mappings in Ihrer Basisklasse. Wenn Sie beispielsweise eine Eins-zu-Eins-Beziehung in Entität A und Entität B wünschen, wenn Sie A als Basisklasse verwenden, muss A einen Konstruktor haben, der B als Argument hat.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.