Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JPA中无状态更新一对多关系的正确方法?_Jpa_Spring Data Jpa - Fatal编程技术网

在JPA中无状态更新一对多关系的正确方法?

在JPA中无状态更新一对多关系的正确方法?,jpa,spring-data-jpa,Jpa,Spring Data Jpa,我有一个用于数据模型的REST接口,该数据模型在实体之间具有多个一对多和多对多关系。虽然多对多关系似乎很容易无状态管理,但我在一对多方面遇到了麻烦。考虑以下一对多关系: 雇员: @ManyToOne @JoinColumn(name = "Company_id") private Company company; 公司: @OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval=true) public

我有一个用于数据模型的REST接口,该数据模型在实体之间具有多个一对多和多对多关系。虽然多对多关系似乎很容易无状态管理,但我在一对多方面遇到了麻烦。考虑以下一对多关系:

雇员:

@ManyToOne
@JoinColumn(name = "Company_id")
private Company company;
公司:

@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval=true)
public Set<Employee> employees = new HashSet<Employee>();
我假设发生这种情况是因为db已经包含了一组雇员,如果任何“旧”雇员也是替换集的一部分,他们就会与数据库中的雇员发生冲突


那么,替换集合的正确方法是什么呢?

我认为您没有比替换现有集合并简单地设置REST响应提供的新集合更好的选择。

我认为您没有比替换现有集合并简单地设置REST响应提供的新集合更好的选择。

首先确保equals得到了正确的实现。根据hibernate规范:

我在合并时遇到了类似的问题。基本上,我必须把公司现有的员工找来。我必须合并对现有员工的任何更改,然后添加任何新员工

    Query query = em.createQuery("select e from Employee e where e.company = '" + company.getId() + "'");
    Collection<Employee> existingEmployees = new LinkedList<Employee>();
    try{
        Iterables.addAll(existingEmployees, (Collection<Employee>) query.getResultList());
    }
    catch(NoResultException nre){
        //No results
    }

    for(Employee existingEmployee : existingEmployees){
        for(Employee employee : company.getEmployees()){
            if(existingEmployee.name().equals(employee.name())){
                employee.setId(existingEmployee.getId());
            }
            employee.setCompany(company);
        }
    }
Query Query=em.createQuery(“从员工e中选择e,其中e.company='”+company.getId()+”);
集合existingEmployees=newlinkedlist();
试一试{
Iterables.addAll(existingEmployees,(Collection)query.getResultList());
}
捕获(NoResultException nre){
//没有结果
}
对于(员工现有员工:现有员工){
for(雇员:company.getEmployees()){
如果(existingEmployee.name().equals(employee.name())){
setId(existingEmployee.getId());
}
员工。设置公司(公司);
}
}

首先确保正确实现了equals。根据hibernate规范:

我在合并时遇到了类似的问题。基本上,我必须把公司现有的员工找来。我必须合并对现有员工的任何更改,然后添加任何新员工

    Query query = em.createQuery("select e from Employee e where e.company = '" + company.getId() + "'");
    Collection<Employee> existingEmployees = new LinkedList<Employee>();
    try{
        Iterables.addAll(existingEmployees, (Collection<Employee>) query.getResultList());
    }
    catch(NoResultException nre){
        //No results
    }

    for(Employee existingEmployee : existingEmployees){
        for(Employee employee : company.getEmployees()){
            if(existingEmployee.name().equals(employee.name())){
                employee.setId(existingEmployee.getId());
            }
            employee.setCompany(company);
        }
    }
Query Query=em.createQuery(“从员工e中选择e,其中e.company='”+company.getId()+”);
集合existingEmployees=newlinkedlist();
试一试{
Iterables.addAll(existingEmployees,(Collection)query.getResultList());
}
捕获(NoResultException nre){
//没有结果
}
对于(员工现有员工:现有员工){
for(雇员:company.getEmployees()){
如果(existingEmployee.name().equals(employee.name())){
setId(existingEmployee.getId());
}
员工。设置公司(公司);
}
}

您能再解释一下我不能明确删除或添加员工是什么意思吗?并给出一些例子吗?因为这是一个REST接口,所以我只收到一个公司对员工集合的PUT请求,可能已经更改了。获取该集合的持久版本并找出哪些员工已被删除或添加,以便我可以显式调用add()和remove(),这似乎更为复杂。您能否解释一下我不能显式删除或添加员工的意思,并给出一些示例?因为这是一个REST接口,我只收到了一个关于公司员工集合的PUT请求,可能已经改变了。获取该集合的持久版本并找出哪些员工已被删除或添加,这样我就可以显式地调用add()和remove(),这似乎更加复杂。这一点很好。事实上,我根本没有实现equals和hashcode方法,但不知何故,代码大部分时间仍然有效。这是一件让我困扰的事情——有时它总是失败,有时我就是无法重现这种情况,不管我修改员工设置多少次。这可能就是使用JPA带来的惊奇。所以,这意味着,在一段关系中(在这种情况下是一个公司),你必须要么玩这个集合(迭代、更新和合并)或者完全删除旧集合并放入一个新集合。这一点很好。事实上,我根本没有实现equals和hashcode方法,但不知何故,代码大部分时间仍然有效。这是一件让我感到困扰的事情——有时它会持续失败,有时我就是无法重现这种情况,无论我修改了多少次该集合员工集合。这可能是使用JPA带来的奇迹。因此,这意味着,在关系中(在本例中为oneToMany),您必须要么使用集合(迭代、更新和合并),要么删除旧集合并放入新集合。
    Query query = em.createQuery("select e from Employee e where e.company = '" + company.getId() + "'");
    Collection<Employee> existingEmployees = new LinkedList<Employee>();
    try{
        Iterables.addAll(existingEmployees, (Collection<Employee>) query.getResultList());
    }
    catch(NoResultException nre){
        //No results
    }

    for(Employee existingEmployee : existingEmployees){
        for(Employee employee : company.getEmployees()){
            if(existingEmployee.name().equals(employee.name())){
                employee.setId(existingEmployee.getId());
            }
            employee.setCompany(company);
        }
    }