![](/img/trans.png)
[英]org.hibernate.AssertionFailure: null identifier @OneToOne relationship
[英]Spring JPA Shared primary key causes org.hibernate.AssertionFailure: null identifier
我正在使用 MySQL 數據庫制作一個 Spring Boot 應用程序,並且我正在嘗試設置類似這個示例的內容(簡化了問題) 其中一些可選實體可以保存有關用戶的額外數據。
這是我設置的簡化示例:Person.java:
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
@Entity
public class Person {
@Id
@Column
@GeneratedValue
private Long id;
@Column
private String name;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "person", optional = true)
@PrimaryKeyJoinColumn
private Car car;
//getters, setters and constructors
public Person() {
super();
}
public Person(Long id, String name) {
super();
this.id = id;
this.name = name;
}
public Person(Long id, String name, Car car) {
super();
this.id = id;
this.name = name;
this.car = car;
}
public Long getId() { return id; }
public String getName() { return name; }
public Car getCar() { return car; }
public void setCar(Car car) { this.car = car; }
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
}
汽車.java:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
@Entity
public class Car {
@Id
@Column
private Long id;
@MapsId
@OneToOne //NOTE A
@JoinColumn(name ="id")
private Person person;
@Column
private String brand;
//Getters, setters and constructors
public Car() {
super();
}
public Car(Long id, Person person, String brand) {
super();
this.id = id;
this.person = person;
this.brand = brand;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Person getPerson() { return person; }
public void setPerson(Person person) { this.person = person; }
public String getBrand() { return brand; }
public void setBrand(String brand) { this.brand = brand; }
}
還有我的測試課:
@SpringBootTest
class BasicOneToOneTest {
@Autowired
PersonRepo persons;
@Autowired
CarRepo cars;
@Test
void test() {
Person dave = new Person(null, "Dave");
persons.save(dave);
Car car = new Car(dave.getId(), dave, "HAS_WHEELS");
cars.save(car);
dave = persons.findById(dave.getId()).get();
assertEquals(true, dave.getCar() != null );
cars.delete(car);
dave = persons.findById(dave.getId()).orElseGet(()->null);
assertEquals(true, dave!=null ); //NOTE B
}
}
當按原樣運行時,我得到org.hibernate.AssertionFailure: null identifier
如果我將 @OneToOne (在note A
)更改為包含cascade = CascadeType.ALL
則空標識符消失,但該人也被刪除。 (在注 B 處測試)
感謝您的幫助,謝謝:)
找到了一個解決方案,我發現運行測試如下有效:
@Test
void test() {
Person dave = new Person(null, "Dave");
persons.save(dave);
Car car = new Car(dave.getId(), dave, "HAS_WHEELS");
dave.setCar(car); //car is set into the parent entity
persons.save(dave); //person is saved instead of the car
dave = persons.findById(dave.getId()).get();
assertEquals(true, dave.getCar() != null );
cars.delete(car);
dave = persons.findById(dave.getId()).orElseGet(()->null); //skip?
assertEquals(true, dave!=null );
}
編輯:此處未按預期刪除汽車
編輯:更改@OneToOne 以使用MERGE
而不是ALL
似乎有效
@OneToOne(cascade = CascadeType.MERGE, mappedBy = "person", optional = true)
@PrimaryKeyJoinColumn
private Car car;
這是我更改后使用的測試:
@Test
void test2() {
Person dave = new Person(null, "Dave");
persons.save(dave);
Car car = new Car(dave.getId(), dave, "HAS_WHEELS");
dave.setCar(car);
persons.save(dave);
dave = persons.findById(dave.getId()).get();
assertEquals(true, dave.getCar() != null , "Dave does not have car assigned");
cars.delete(car);
dave = persons.findById(dave.getId()).orElseGet(()->null);
assertEquals(true, dave!=null, "Dave deleted" );
assertEquals( false , cars.existsById(car.getId()), "Car not deleted" );
}
如果有人有更好的解決方案,我仍然會感興趣。 但這暫時有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.