我正在尝试使用entityManager.remove(parent)
删除具有一对多父子关系的父实体。但是,从SQL日志中我看到OpenJPA首先调用UPDATE
并尝试为NOT NULL
字段设置null。
executing prepstmnt 773394836 UPDATE child SET parent_id = ? WHERE parent_id = ? [params=(null) null, (long) 16]
executing prepstmnt 1127292223 DELETE FROM parent WHERE id = ? [params=(long) 16]
executing prepstmnt 1297966852 DELETE FROM child WHERE lookup_id = ? AND parent_id = ? [params=(int) 1, (long) 16]
如何配置我的课程以防止首次UPDATE
来电?
我的课程:
@Entity
@Table(name = "parent")
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
orphanRemoval = true)
@JoinColumn(name = "parent_id")
private List<Child> children;
// getters, etc.
}
@Entity
@Table(name = "child")
@IdClass(ChildPrimaryKey.class)
public class Child {
@Id
@Column(name = "parent_id", nullable = false, updatable = false)
private long parentId;
@Id
@Column(name = "lookup_id")
private int lookupId;
@ManyToOne
@JoinColumn(name = "parent_id", referencedColumnName = "id",
nullable = false, insertable = false, updatable = false)
private Parent parent;
// getters, etc.
}
我的数据库表(在MySQL中):
CREATE TABLE IF NOT EXISTS `parent` (
`id` BIGINT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(50) NOT NULL ,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `child` (
`lookup_id` INT NOT NULL ,
`parent_id` BIGINT NOT NULL ,
PRIMARY KEY (`parent_id`, `lookup_id`) ,
INDEX `fk_library_code_idx` (`parent_id` ASC) ,
CONSTRAINT `fk_library_code`
FOREIGN KEY (`parent_id` )
REFERENCES `parent` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
答案 0 :(得分:2)
我不是完全确定是什么导致JPA决定执行这些查询,但是,我注意到你的映射存在一些问题。
首先,您没有在mappedBy
注释中指定@OneToMany
元素(即您没有告诉OpenJPA Child
是该关系的所有者)。这是我第一次猜到你为什么会看到这种行为。来自API specification:
如果关系是双向的,则mappedBy元素必须是 用于指定实体的关系字段或属性 是这段关系的所有者。
要解决此问题,请更改Parent
的{{1}}以包含@OneToMany
元素并删除mappedBy
:
@JoinColumn
此外,我注意到您尝试将 @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,
fetch = FetchType.EAGER, orphanRemoval = true)
private List<Child> children;
的ID用作Parent
ID的一部分,并在Child
上有两个字段映射到同一个PK列( Child
和parent
)。处理此问题的首选方法是@MapsId
:
parentId
答案 1 :(得分:0)
这是一个假设。
我认为正在发生的是UPDATE语句是为了避免在执行DELETE时违反约束。或者至少,这就是OpenJPA 认为需要进行更新的原因。
有两种可能性:
我建议您使用相关的“父”和“子”行设置数据库,然后尝试手动删除一行或另一行而不用做更新。这将确定UPDATE是否真的 。
根据结果,忽略问题,尝试更改架构和/或注释,或者查看OpenJPA问题跟踪器中是否存在错误报告/解决方法。 (你也可以尝试一些实验来看看Hibernate的行为方式是否相同和/或这是否特定于MySQL。)