我正在使用Spring Data JPA来Map应用程序中两个实体之间的OneToOne关系。实体是DM和DM_DATA,其中每个DM记录都有一个对应的DM_DATA记录。
DM表具有到DM_DATA表的外键约束,使用DM_DATA_ID列Map到DMD_DATA_ID(DM_DATA中的主键)。在JPA实体中使用DM实体上的@OneToOne和@JoinColumn注解以及DM_DATA实体上的@OneToOne(mappedBy =“dmData”)注解来定义关系。
我还将CASCADE选项添加到DM实体中的@OneToOne注解中,以启用级联删除。
父级:
@Entity
@Table(name = "DM")
public class FileDm {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "DM_FILE_ID")
private long id;
@OneToOne(
fetch = FetchType.EAGER,
cascade = {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.REMOVE},
orphanRemoval = true
)
@JoinColumn(name = "DMD_DATA_ID", referencedColumnName = "DMD_DATA_ID")
private DmData dmData;
@ManyToOne(optional=true)
@JoinColumn(name="DM_DCMT_ID", nullable=true)
private DmType dmType;
...
}
孩子:
@Entity
@Table(name = "DM_DATA")
public class DmData {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "DMD_DATA_ID")
private long code;
@OneToOne(mappedBy = "dmData")
private FileDm fileDm;
@Column(name = "DMD_DATA")
private String data;
...
}
另外,我还编写了一个sql脚本来更改DB方案并进行迁移:
ALTER TABLE DM ADD COLUMN DM_DATA_ID bigint(20);
CREATE TABLE DM_DATA (
DMD_DATA_ID bigint(20) NOT NULL AUTO_INCREMENT,
TEMP_DATA_ID bigint(20) NOT NULL,
DMD_DATA longblob,
PRIMARY KEY (DMD_DATA_ID)
) ENGINE=InnoDB CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
INSERT INTO DM_DATA(TEMP_DATA_ID, DMD_DATA)
(SELECT d.DM_FILE_ID, d.DM_DATA
FROM DM d
WHERE d.DM_DATA IS NOT NULL);
UPDATE DM d
INNER JOIN DM_DATA dd
ON d.DM_FILE_ID = dd.TEMP_DATA_ID
SET d.DM_DATA_ID = dd.DMD_DATA_ID;
ALTER TABLE DM_DATA DROP TEMP_DATA_ID;
ALTER TABLE DM DROP DM_DATA;
所以我最终得到了这些DB方案:
DM | CREATE TABLE `DM` (
`DM_FILE_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`DM_DATA_ID` bigint(20) DEFAULT NULL,
`DM_DCMT_ID` varchar(3) DEFAULT NULL,
PRIMARY KEY (`DM_FILE_ID`),
KEY `FK_DM_DMTYPE_idx` (`DM_DCMT_ID`),
CONSTRAINT `FK_DM_DMTYPE` FOREIGN KEY (`DM_DCMT_ID`) REFERENCES `DMTYPE` (`DCMT_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT `FK_DM_DATA_ID` FOREIGN KEY (`DM_DATA_ID`) REFERENCES `DM_DATA` (`DMD_DATA_ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci |
| DM_DATA | CREATE TABLE `DM_DATA` (
`DMD_DATA_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`DMD_DATA` varchar(255) DEFAULT NULL,
PRIMARY KEY (`DMD_DATA_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci |
但是,当我通过存储库方法或通过db中的delete语句删除DM记录时,DM_DATA记录不会被删除。
我尝试使用DMD_DATA_ID列将外键约束添加到DM_DATA表,但这并没有解决问题。我还尝试切换外键关系的方向,但这导致插入新记录时出现不同的错误。
有没有办法在JPA中正确配置OneToOne关系,并在SQL脚本中镜像它,以启用子实体的级联删除?
1条答案
按热度按时间u5i3ibmn1#
我通过改变关系的方向来解决这个问题:
父级:
孩子:
在sql模式定义和迁移脚本中,我将TEMP_DATA_ID更改为DMD_FILE_ID,并添加了外键约束
我还是不明白为什么它不能按原来的方式工作。