Hibernate 抛出 "NULL not allowed for column",因为在使用 @MapsId 时 SQL INSERT 中缺少 JPA OneToOne 关系 FK

Hibernate throws "NULL not allowed for column" as the JPA OneToOne relation FK is missing in the SQL INSERT when using @MapsId

关于我的 OneToOne 关系,我得到: NULL not allowed for column "USER_ID"; SQL statement: insert into customer_order (id, enabled, orden_id) values (null, ?, ?).

它实际上是 null 因为 INSERT 查询中不存在。但是,在执行 save(customerOrder).

时,值 USER 被填充到 customerOder 实体中
@Getter
@SuperBuilder
@MappedSuperclass
@NoArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public abstract class AbstractEntity {

    @Id
    @EqualsAndHashCode.Include
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Setter
    @Default
    @Column(columnDefinition = "BOOLEAN DEFAULT 'true'", nullable = false)
    private Boolean enabled = Boolean.TRUE;
}

@Getter
@Setter
@Entity
@Table(name = "customer_order")
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public class CustomerOrderEntity extends AbstractEntity {

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId("id")
    private UserEntity user;

       //other values
}

@Data
@Entity
@Table(name = "user")
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public class UserEntity extends AbstractEntity {

    @NaturalId
    @EqualsAndHashCode.Include
    @Column(length = 28, unique = true, nullable = false)
    private String uuid;

//other values
}

我希望 customerOrder 与填充数据一起保存在数据库中。

您的代码完全按照您指定的方式工作。

如果你有一个共享键(你使用@MapsId),Hibernate 不会为外键使用一个单独的列。这就是插入查询不包含 user_id 列的原因。

最重要的是,CustomerOrderEntity 中的 id 一方面是 auto-generated(在超类中定义),另一方面映射另一个实体的 id。这些是相互矛盾的要求。

使用 @MapsId 允许您使用子 table 主键作为父 table 主键的外键。

如果启用 hbm2ddl 工具,您将看到 customer_order table 将不包含 user_id 列。

但是,由于您之前生成了数据库架构并且您有一个带有专用 user_id 列的 customer_order table,因此您需要删除 @MapsId

@OneToOne(fetch = FetchType.LAZY)
private UserEntity user;

这样,user 关联将使用 user_id 外键列。