Die Nicht-Null-Eigenschaft verweist auf einen vorübergehenden Wert. Die vorübergehende Instanz muss vor dem aktuellen Vorgang gespeichert werden
Lesezeit: 5 Minuten
Ich habe zwei Domänenmodelle und einen Spring REST Controller wie unten:
@Entity
public class Customer{
@Id
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
@Entity
public class Country{
@Id
@Column(name="COUNTRY_ID")
private Integer id;
// other stuff with getters/setters
}
Spring REST-Controller:
@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Create new customer
*/
@RequestMapping( method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public com.salesmanager.web.entity.customer.Customer createCustomer(@Valid @RequestBody Customer customer, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
customerService.saveOrUpdate(customer);
return customer;
}
// other stuff
}
Ich versuche, den oben genannten REST-Dienst mit dem folgenden JSON als Text aufzurufen:
Wobei der Ländercode 1 bereits in der Ländertabelle vorhanden ist. Das Problem besteht darin, dass beim Aufrufen dieses Dienstes die folgende Fehlermeldung angezeigt wird:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country
Jede Hilfe wird geschätzt!
Raju Rudru
Versuchen Sie, CascadeType.ALL einzufügen
@OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
Ok, dann tun Sie etwas. Ihr Kundenobjekt verfügt über ein Länderobjekt mit der ID 1. Dieses Länderobjekt befindet sich jedoch nicht im Persistenzstatus. Rufen Sie zunächst das Länderobjekt ab, indem Sie die Länder-ID senden. Legen Sie das aus der Datenbank abgerufene Länderobjekt als Kundenobjekt fest. Anschließend Kundenobjekt speichern. Ich hoffe, dass es dieses Mal keine Fehlermeldung gibt.
– Raju Rudru
29. September 2013 um 6:29
Seltsamerweise funktioniert CascadeType.ALL für mich, wenn dies nicht der Fall ist: @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
– Sam Barnum
27. November 2019 um 12:02 Uhr
djejaquino
Ich hatte ein ähnliches Problem. Zwei Einheiten: Dokumentieren Und Status. Dokumentieren hatte eine Beziehung OneToMany mit Statusdas die Geschichte von repräsentierte Status Die Dokumentieren hatte.
Es gab also eine @NotNull@ManyToOne Referenz von Dokumentieren innen Status.
Außerdem musste ich das Tatsächliche wissen Status von Dokumentieren. Also brauchte ich dieses Mal eine andere Beziehung @OneToOneAuch @NotNullinnen Dokumentieren.
Das Problem war: Wie kann ich beide Entitäten beim ersten Mal beibehalten, wenn beide eine hatten @NotNull Bezug auf den anderen?
Die Lösung war: entfernen @NotNull Referenz von actualStatus Referenz. Auf diese Weise konnten beide Entitäten bestehen bleiben.
Dies beantwortet die Frage nicht wirklich. Wenn Sie eine andere Frage haben, können Sie diese stellen, indem Sie auf „Frage stellen“ klicken. Sie können auch ein Kopfgeld hinzufügen, um mehr Aufmerksamkeit auf diese Frage zu lenken, sobald Sie über genügend Reputation verfügen.
– Skolima
11. September 2014 um 20:44
Ich habe eine Lösung für mein Problem vorgestellt, die ähnlich war. Hat nichts mit einer neuen Frage zu tun.
– Djejaquino
14. November 2014 um 13:55 Uhr
Um nur ein weiteres Szenario hinzuzufügen, das mich zu genau demselben Fehler geführt hat:
Stellen Sie sicher, dass eventuell vorhandene Rückwärtsverweise nicht null sind.
Speziell in meinem Fall habe ich verwendet Mapstruct um einige Felder der Entität zu aktualisieren, z
Und meine schlechte Umsetzung von MyClassMapper führte die Rückverweise von dbInstance Felder, auf die festgelegt werden soll null wann sie darauf hinweisen sollten dbInstance.
Ich habe den gleichen Fehler erhalten und so habe ich ihn gelöst:
1. Entität:
@Entity
public class Person implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int personId;
private String name;
private String email;
private long phoneNumber;
private String password;
private String userType;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "personCustomer", cascade
= CascadeType.ALL)
private Customer customer;
2. Entität:
@Entity
public class Customer implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade =
CascadeType.ALL)
@JoinColumn(name = "person_customer")
@JsonIgnore
private Person personCustomer;
Mein Controller:
@PostMapping("/customer/registration")
public PersonCustomer addCustomer(@RequestBody Person person)
{
Customer customer = new Customer(person);
person.setCustomer(customer);
Customer cust = customerRepo.save(customer);
logger.info("{}", cust);
Optional<Person> person_Cust =
personRepo.findById(cust.getPersonCustomer().getPersonId());
Person personNew = person_Cust.get();
PersonCustomer personCust = new PersonCustomer();
if(cust.equals(null))
{
personCust.setStatus("FAIL");
personCust.setMessage("Registration failed");
personCust.setTimestamp(personCust.timeStamp());
}
personCust.setStatus("OK");
personCust.setMessage("Registration OK");
personCust.setTimestamp(personCust.timeStamp());
personCust.setPerson(personNew);
return personCust;
}
Das Problem wurde gelöst, als ich „person.setCustomer(customer);“ hinzufügte. Da beide POJO-Klassen aufeinander verweisen, müssen wir vor der Verwendung der JPA-Repository-Methode (customerRepo.save(customer)) die gegenseitige Referenz „festlegen“.
Péter Márkus
Ich hatte genau das gleiche Problem. Die Lösung scheint darin zu bestehen, den JSON wie folgt zu senden:
Ich schätze @RequestBody versucht, einer Entität kein einziges Feld zuzuordnen, da dies der Fall ist Kunde Instanz verweist auf a Land Beispiel.
(Ich habe auf ähnliche Weise zwei Entitäten verbunden. In der Datenbank wurden bereits Datensätze für die referenzierte Entität (in Ihrem Fall „Land“) erstellt, aber die Entitätserstellung (in Ihrem Fall „Kunde“) mit einem JSON lieferte dieselbe Fehlermeldung. Für mich CascadeType .ALL hat nicht geholfen, aber die oben geschriebene Änderung im JSON hat das Problem gelöst. Für die weitere Konfiguration kann natürlich CascadeType in Betracht gezogen werden.)
Miladesnovakaina
Sie sollten Folgendes ändern:
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
Zu :
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID")
private Country country;
Löschen Sie einfach die Nullable-Einstellung.
14523100cookie-checkDie Nicht-Null-Eigenschaft verweist auf einen vorübergehenden Wert. Die vorübergehende Instanz muss vor dem aktuellen Vorgang gespeichert werdenyes