为啥向现有行添加新行时,链接/联结表行的主 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 关系中关联 ServiceServicePackage 实体,因为服务可以属于许多服务包,而服务包可能有多个不同的服务与之关联。

联结表具有以下列: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 会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

将最后一个表格行的选定值复制到新行

Cassandra 数据如何更新

JQuery追加到表行的末尾而不是Tbody?

根据R中现有行的值插入行

向MongoDB中的现有集合添加具有大量行的新字段

如何在按钮单击时将新行添加到数据库中的jTable而不清除现有行