为什么在添加新行时,链接/联结表行的主ID在现有行上会发生变化?

时间:2015-10-20 13:30:17

标签: java hibernate sql-server-2012 many-to-many junction-table

我在WildFly8上运行一个Web项目,我的数据库是SQL Server 2012。

我创建了一个联结表service_service_package,以Service关系关联ServicePackageManyToMany个实体,因为服务可以属于许多服务包,而服务包可能有多个与他们相关的不同服务。

联结表包含以下列: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
@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

例如:我以上述方式将ServicePackage(id 4)添加到服务(id 6),然后保存服务。现在联结表得到以下条目,例如:

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 个答案:

答案 0 :(得分:0)

连接到某个服务的service_service_package联结表中所有“链接行”的所有现有主要ID都被覆盖并在新ServicePackage链接到同一服务(或从中删除)时增加的原因就是,实体服务中的集合servicePackages是一个列表。

我将该集合更改为HashSet,问题解决了。原因是,与ArrayList不同,HashSet不接受重复,因此现有链接保持原样,其ID不变。