lol*_*o92 3 java postgresql spring-boot spring-data-jdbc
我想使用 Spring Data JDBC 和 PostgreSQL 建模一对一关系,但我在以正确的方式设置根聚合时遇到问题。
\n\n有以下场景:图片,SQL
\n每个引擎都是唯一的,car具有唯一的列engine_id,该列是 的外键engine.id,同样适用于truck。因此,汽车和卡车应该是根聚合,因此当删除汽车或卡车时,引擎表中引用的行也应该被删除。
\n\n\n如果多个聚合引用同一实体,则该实体不能成为引用它的聚合的一部分,因为它只能是一个聚合的一部分。
\n
所以问题是:
\n\ncar并truck反映更改engine?这是我的看法,虽然行不通,但应该澄清我想要完成的任务。
\n\n汽车.java
\n\npackage com.example.dao.model;\n\nimport org.springframework.data.annotation.Id;\nimport org.springframework.data.domain.Persistable;\nimport org.springframework.data.relational.core.mapping.Column;\nimport org.springframework.data.relational.core.mapping.Table;\n\nimport java.util.UUID;\n\n@Table("car")\npublic class Car implements Persistable<UUID> {\n\n @Id\n private UUID id;\n\n String brand;\n\n String model;\n\n @Column("engine_id")\n Engine engine;\n\n public void setId(UUID id) {\n this.id = id;\n }\n\n @Override\n public UUID getId() {\n return id;\n }\n\n @Override\n public boolean isNew() {\n return id == null;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n引擎.java
\n\npackage com.example.dao.model;\n\nimport org.springframework.data.annotation.Id;\nimport org.springframework.data.domain.Persistable;\nimport org.springframework.data.relational.core.mapping.Table;\n\nimport java.time.LocalDateTime;\nimport java.util.UUID;\n\n@Table("engine")\npublic class Engine implements Persistable<UUID> {\n\n @Id\n private UUID id;\n\n String name;\n\n LocalDateTime dateCreated;\n\n String type;\n\n public void setId(UUID id) {\n this.id = id;\n }\n\n @Override\n public UUID getId() {\n return id;\n }\n\n @Override\n public boolean isNew() {\n return id == null;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n卡车.java
\n\npackage com.example.dao.model;\n\nimport org.springframework.data.annotation.Id;\nimport org.springframework.data.domain.Persistable;\nimport org.springframework.data.relational.core.mapping.Column;\nimport org.springframework.data.relational.core.mapping.Table;\n\nimport java.util.UUID;\n\n@Table("truck")\npublic class Truck implements Persistable<UUID> {\n\n @Id\n private UUID id;\n\n String brand;\n\n String model;\n\n Integer cargoMaxWeight;\n\n String truckType;\n\n @Column("engine_id")\n Engine engine;\n\n public void setId(UUID id) {\n this.id = id;\n }\n\n @Override\n public UUID getId() {\n return id;\n }\n\n @Override\n public boolean isNew() {\n return id == null;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
我看到有四个选项可以用 Java 对此进行建模。请注意,其中大多数都需要调整您的数据库架构。
一般问题是 Spring Data JDBC 假定引用的实体 ( Engine) 在其表中有一列引用所属实体 ( Car/ Vehicle)。这有一个问题: https: //jira.spring.io/browse/DATAJDBC-128
从这里开始,您有以下选项:
添加到引擎表的列,产生如下所示的实体和模式(所有实体都减少到与问题相关的最小程度):
public class Car {
@Id
Long id;
String name;
Engine engine;
}
public class Truck {
@Id
Long id;
String name;
Engine engine;
}
public class Engine {
String name;
}
CREATE TABLE CAR (
id BIGINT IDENTITY,
NAME VARCHAR(200)
);
CREATE TABLE TRUCK (
ID BIGINT IDENTITY,
NAME VARCHAR(200)
);
CREATE TABLE ENGINE (
TRUCK BIGINT,
CAR BIGINT,
NAME VARCHAR(200),
FOREIGN KEY (TRUCK) REFERENCES TRUCK (ID),
FOREIGN KEY (CAR) REFERENCES CAR (ID)
);
Run Code Online (Sandbox Code Playgroud)
我在 GitHub 上提供了一个完整的示例: https: //github.com/schauder/so-sd-jdbc-multipleonetoone。
如果您不喜欢这两列,您可以修改映射以对两个引用使用同一列。但是你必须确保 和 的 idCar是Vehicle不同的。即使这样,这种方法也存在一个大问题:
deleteAll在Car存储库或Truck车辆上将删除所有引擎!
所以不推荐这种方法!
如果您仍然想使用它,这里是模式和实体的代码。
public class Car {
@Id
Long id;
String name;
@Column(value = "vehicle")
Engine engine;
}
public class Truck {
@Id
Long id;
String name;
@Column(value = "vehicle")
Engine engine;
}
public class Engine {
String name;
}
CREATE TABLE CAR (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY ,
NAME VARCHAR(200)
);
CREATE TABLE TRUCK (
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH -1, INCREMENT BY -1) PRIMARY KEY ,
NAME VARCHAR(200)
);
CREATE TABLE ENGINE (
VEHICLE BIGINT,
NAME VARCHAR(200),
);
Run Code Online (Sandbox Code Playgroud)
完整的示例在此提交中:https://github.com/schauder/so-sd-jdbc-multipleonetoone/tree/5570979ef85e30fe7a17a8ce48d867fdb79e212a。
有两个单独的Engine类和表。一个用于Cars,一个用于Trucks。
如果您不想或无法更改数据库架构,您可以考虑Engine、Car和Truck三个单独的聚合。你会有一个Long engineIdinCar和 in Truck。然后可以使用的事件侦听器来AfterDeleteEvent完成级联删除。
| 归档时间: |
|
| 查看次数: |
12037 次 |
| 最近记录: |