具有相同ID的OneToOne映射

时间:2017-12-23 20:58:00

标签: java spring hibernate spring-boot

我有两个实体类:

@Data @Entity
public class MainEntity {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer mainId;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private SubEntity subEntity;
}

@Data @Entity
public class SubEntity {

    @Id
    private Integer mainId;
}

我在this answer中找到了这个架构。 我认为它可以解决所有问题,但是当我尝试保存已填充的MainEntity时,我遇到了下一个异常:

  

org.hibernate.id.IdentifierGenerationException:在调用save()之前必须手动分配此类的ID:com.example.demo.SubEntity

我做错了什么?因为我使用一对一映射,所以我不希望在我的子实体中有另一个主键。此外,我不需要从SubEntityMainEntity的反向链接。

我用来测试它的代码片段:

@Bean
public CommandLineRunner test(MainEntityRepository repo) {
    return args -> {
        MainEntity main = new MainEntity();
        main.setSubEntity(new SubEntity());
        repo.save(main);

        repo.findAll().forEach(System.out::println);
    };
}

您可以在github上找到我的示例项目here

2 个答案:

答案 0 :(得分:1)

试试这个:

@Data @Entity
public class MainEntity {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer mainId;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "mainEntity", optional = false)
    @PrimaryKeyJoinColumn
    private SubEntity subEntity;
}

@Data @Entity
public class SubEntity {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer mainId;

    @MapsId
    @JoinColumn(name = "mainId")
    @OneToOne(optional = false)
    private MainEntity mainEntity;
}

答案 1 :(得分:0)

问题是你不能插入一个带空值的PK,因为你从未设置过id,hibernate告诉你必须在保存实体之前这样做。

  

解决方案:

     

1-在保存实体之前手动设置ID。

     

2-使用@GeneratedValue激活@Id属性(strategy =   GenerationType.IDENTITY)tio自动生成值。

希望这有帮助。