我試圖刪除使用entityManager.remove(parent)
具有一對多的父子關係的父實體。但是,從SQL日誌中,我看到OpenJPA首先調用UPDATE
,並試圖爲NOT NULL
字段設置爲空。爲什麼OpenJPA在DELETE之前調用UPDATE?
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;
使用mappedBy代替@JoinColumn會導致插入異常,因爲OpenJPA會嘗試將0設置爲parent_id:引發原因:org.apache.openjpa.lib.jdbc.ReportingSQLException:無法添加或更新子行:外鍵約束失敗(''test''.''child'',CONSTRAINT''fk_library_code'' FOREIGN KEY(''parent_id'')REFERENCES''parent''(''id'')ON DELETE CASCADE ON UPDATE CASCADE){prepstmnt 972578961插入到孩子(lookup_id,parent_id)VALUES(?,?)[params =(int)1,(long)0]} [code = 1452,state = 23000]'。我認爲mappedBy是用於連接表的。 –
在進一步研究之後,使用'mappedBy'是在這種情況下正確的方法。但是,兒童和父母實體必須分開管理。例如,'parent_id'必須設置爲正確的值,子實體必須手動刪除等。在這種情況下'@ MapsId'不需要。 –
@VictorLyuboslavsky如果您使用'@ MapsId','parentId'會自動從'Parent'複製給您。您的用例與[documentation](http://docs.oracle.com/javaee/6/api/javax/persistence/MapsId.html)中描述的內容完全相同:「_設計ManyToOne或OneToOne關係屬性,該屬性提供映射...父實體的簡單主鍵「。此外,你不應該分開移除孩子......你能顯示你的更新實體嗎? – DannyMo