Spring Data JPA - 删除子实体而不是在更新时设置为 null?

SKP*_*SKP 4 java mysql spring jpa spring-data

我有以下域模型

users
----
id (PK)
name

orders
------
id (PK)
userid (PK)
name
Run Code Online (Sandbox Code Playgroud)

Orders.userid 引用 User 中的 id,并且是复合主键的一部分。(我需要主键中的 userid,因为它是分区键,并且在 MySQL 中,如果没有分区键,我们无法创建主键)

在使用 JPA 更新用户时,如果我尝试使用以下命令清除关联的订单集合

User user = userRepository.getOne(id);
user.getOrders().clear();
userRepository.save(user);
Run Code Online (Sandbox Code Playgroud)

JPA 首先尝试将关联订单上的 userid 设置为 null,然后删除该行。由于 userid 不可为 null 并且是主键的一部分,因此此操作会失败。有没有办法告诉 JPA 它只需要删除订单行而不首先将 userid 列设置为 null ?

更新

映射:我的映射是这样的:

@Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public Long id;

    @Column(name="name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name="userid", referencedColumnName = "id", insertable = true, updatable = true)
    @Fetch(FetchMode.JOIN)
    private Set<Order> orders;

}

@Entity
@Table(name = "orders")
@IdClass(Order.OrderPk.class)
public class Order implements Serializable {

    @Id
    @Column(name="id")
    private Long id;

    @Id
    @Column(name="userid")
    private Long userId;

    @Column(name="name")
    private String name;

    public static class OrderPk implements Serializable  {

        private Long id;

        private Long userId;
    }
}
Run Code Online (Sandbox Code Playgroud)

您能告诉我映射会有什么变化吗?

更新:

也尝试了以下映射:

@Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id", nullable = false)
    public Long id;

    @Column(name="name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "orderPk.user")
    @Fetch(FetchMode.JOIN)
    private Set<Order> orders;
}

@Entity
@Table(name = "orders")
public class Order implements Serializable {

    @EmbeddedId
    private OrderPk orderPk;

    @Column(name="name")
    private String name;

    @Embeddable
    public static class OrderPk implements Serializable {

        @GeneratedValue
        @Column(name="id", insertable = false, updatable = false, nullable = false)
        private Long id;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name="userid", referencedColumnName = "id", insertable = false, updatable = false, nullable = false)
        private User user;
    }
}
Run Code Online (Sandbox Code Playgroud)

插入时,它抱怨说“为:class Order 生成了 null id”(也尝试过 insertable=true 和 updatetable=true)

小智 5

您可以使用标识符保留连接,并确保删除操作不会尝试使用集合上的可更新和可插入注释将 null 写入集合 FK。

@Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id", nullable = false)
    public Long id;

    @Column(name="name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch =     FetchType.EAGER)
    @JoinColumn(name = "userId", updatable = false, insertable = false)
    private Set<Order> orders;
}

@Entity
@Table(name = "orders")
public class Order implements Serializable {

    @Id
    @Column(name="id")
    private Long id;

    @Column(name="userid")
    private Long userId;

    @Column(name="name")
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

@JoinColumn(name = "userId", 可更新 = false, 可插入 = false)

部分表示子表不会更新,但可以删除