I am trying to achieve @OneToOne
association, using the same @Id
between a Car
and a Person
. A Person
is has an optional Car
, but a Car
has a required Person
(hence I need a foreign key inside "cars" table pointing an existing Person
):
@Entity
@Table(name = "persons")
public class Person {
@Id
@Column(name = "name")
private String name;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "person")
private Car car;
/**
* For hibernate
*/
@SuppressWarnings("unused")
private Person() {
}
public Person(String name) {
super();
this.name = name;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
}
@Entity
@Table(name = "cars")
public class Car {
@Id
@Column(name = "name")
private String name;
@MapsId
@OneToOne
@JoinColumn(name = "name")
@OnDelete(action = OnDeleteAction.CASCADE)
private Person person;
public Car() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
public interface PersonRepository extends CrudRepository<Person, String> {
}
My test case:
@Autowired
private PersonRepository personRepository;
@Test
public void test() {
Person mike = new Person("Mike");
personRepository.save(mike); //Saved sucessfully
Person alice = new Person("Alice");
Car car = new Car();
car.setPerson(alice);
car.setName(alice.getName());
alice.setCar(car);
personRepository.save(alice); //error
}
Stacktrace:
org.springframework.orm.jpa.JpaSystemException: attempted to assign id from null one-to-one property [com.project.entity.Car.person]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.project.entity.Car.person]
I followed this solution on how to have a shared Id. The schema in database looks to be fine, and works exactly as I want. If i delete a Car, nothing happens. If I delete a person who owns a Car
, his Car
will be deleted from database as well.
The question is simple. What do I do wrong?
In case it plays any role (I doubt it), this is my datasource properties:
spring.jpa.hibernate.dll-auto = create-drop
spring.datasource.url=jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
(Disclaimer: It was not meant to be a Q&A)
The problem is in @MapsId
annotation. Changing it to:
@MapsId("name") //Here
@OneToOne
@JoinColumn(name = "name")
@OnDelete(action = OnDeleteAction.CASCADE)
private Person person;
seems to fix the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.