为啥向现有行添加新行时,链接/联结表行的主 ID 会发生变化?
Posted
技术标签:
【中文标题】为啥向现有行添加新行时,链接/联结表行的主 ID 会发生变化?【英文标题】:Why the primary id of a link / junction table row changes on existing rows when new row is added to it?为什么向现有行添加新行时,链接/联结表行的主 ID 会发生变化? 【发布时间】:2015-10-20 13:30:17 【问题描述】:我在 WildFly8 上运行一个 Web 项目,我的数据库是 SQL Server 2012。
我创建了一个联结表 service_service_package
以在 ManyToMany
关系中关联 Service
和 ServicePackage
实体,因为服务可以属于许多服务包,而服务包可能有多个不同的服务与之关联。
联结表具有以下列:id、service_id 和 service_package_id。这是创建所述联结表的 SQL 脚本:
CREATE TABLE service_service_package
(
id BIGINT NOT NULL IDENTITY(1,1),
service_id BIGINT NOT NULL,
service_package_id BIGINT NOT NULL,
PRIMARY KEY (id)
);
这是服务实体的相关部分:
@Entity
@Table(name = "service")
public class Service
@ManyToMany(targetEntity=ServicePackage.class, fetch=FetchType.LAZY)
@JoinTable(name = "service_service_package",
joinColumns =
@JoinColumn(name = "service_id"),
inverseJoinColumns =
@JoinColumn(name = "service_package_id")
)
private List<ServicePackage> servicePackages;
@Transient
public void addServicePackage(ServicePackage sp)
if (!this.servicePackages.contains(sp))
this.servicePackages.add(sp);
...
这是 ServicePackage Entity 的相关部分:
@Entity
@Table(name = "service_package")
public class ServicePackage
@ManyToMany(targetEntity=Service.class, mappedBy="servicePackages")
private List<Service> services = new ArrayList<>();
...
我对服务有看法。视图的一部分是与服务关联的 ServicePackage 的列表。当我将 ServicePackages 添加到列表中并在该视图中按下保存按钮时,该视图会保留服务,该列表中所有新添加的服务都将与列表中的 ServicePackages 相关联。
这是来自上述视图的相关代码:
for (ServicePackage sp : spList.getTempSpList())
service.addServicePackage(sp);
service = (Service) service.save();
save 方法将服务持久化并创建到联结表的条目。
现在,所有这些都可以正常工作,但是每次将新的 ServicePackage 添加到列表并保存服务时,联结表中的现有链接也会获得递增的 id,即使 addServicePackage 中的服务类只添加尚未与服务关联的服务包
例如:我按照上面描述的方式将一个ServicePackage(id 4)添加到一个Service(id 6)中,并保存该Service。现在联结表得到以下条目,例如:
id service_id service_package_id
-------------------------------------------------
1 6 4
现在,例如,在同一个视图中,我将另一个 ServicePackage(id 11) 添加到列表中,然后像往常一样保存该服务。那么表格是这样的:
id service_id service_package_id
-------------------------------------------------
2 6 4
3 6 11
因此,联结表中第一个链接的 id 从 1 更改为 2。 即使该方法仅将 ServicePackage(id 11) 添加到与 Service 关联的 ServicePackage 列表中,因为它认识到第一个已经存在(我已经用 Println 测试过。)
我的问题是,如何防止联结表中前一个链接的 id 在该链接未更改时增加。这意味着删除了一行并添加了一个新行。我希望第一行的 id 保持为 1。 有什么想法吗,谢谢?
【问题讨论】:
【参考方案1】:当新的 ServicePackage 链接到(或从中删除)同一服务时,链接到某个服务的 service_service_package 联结表中所有“链接行”的所有现有主 ID 都被覆盖和递增的原因很简单,实体 Service 中的集合 servicePackages 是一个列表。
我将该集合更改为 HashSet,问题就解决了。原因是与 ArrayList 不同,HashSet 不接受重复,因此现有链接保持原样,其 id 不变。
【讨论】:
以上是关于为啥向现有行添加新行时,链接/联结表行的主 ID 会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章