Hibernate 抱怨 @OneToOne 中的 @Id 为空,即使它不为空

Posted

技术标签:

【中文标题】Hibernate 抱怨 @OneToOne 中的 @Id 为空,即使它不为空【英文标题】:Hibernate complains for null @Id in @OneToOne even if it is not null 【发布时间】:2020-06-15 22:20:14 【问题描述】:

我正在尝试实现@OneToOne 关联,在CarPerson 之间使用相同的@IdPerson 有一个可选的Car,但Car 有一个必需的Person(因此我需要在“汽车”表内有一个外键指向现有的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> 


我的测试用例:

@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

堆栈跟踪:

org.springframework.orm.jpa.JpaSystemException: 试图分配 id 从 null 一对一属性 [com.project.entity.Car.person]; 嵌套异常是 org.hibernate.id.IdentifierGenerationException: 试图从空的一对一属性分配 id [com.project.entity.Car.person]

我关注了this solution,了解如何拥有一个共享 ID。数据库中的模式看起来很好,并且完全按照我的意愿工作。如果我删除汽车,什么也不会发生。如果我删除一个拥有Car 的人,他的Car 也会从数据库中删除。

问题很简单。 我做错了什么?

如果它扮演任何角色(我对此表示怀疑),这是我的数据源属性:

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

【问题讨论】:

【参考方案1】:

(免责声明:这不是问答)

问题出在@MapsId 注释中。将其更改为:

@MapsId("name") //Here
@OneToOne
@JoinColumn(name = "name")
@OnDelete(action = OnDeleteAction.CASCADE)
private Person person;

似乎可以解决问题。

【讨论】:

这需要我 1.5 天:/

以上是关于Hibernate 抱怨 @OneToOne 中的 @Id 为空,即使它不为空的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate/JPA @OneToOne 返回空指针异常

Hibernate @OneToOne 单向映射...级联删除

为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?

Hibernate @OneToOne 映射不加入列?

hibernate/jpa double OneToOne 与一个实体的双向关系

jpa hibernate @OneToOne @JoinColumn referencedColumnName 被忽略