2

エンティティ間に複数の一対多および多対多の関係を持つデータモデル用の REST インターフェイスがあります。多対多の関係はステートレスに管理するのは簡単に思えますが、私は 1 対多で問題を抱えています。次の 1 対多の関係を考えてみましょう。

従業員:

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

会社:

@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval=true)
public Set<Employee> employees = new HashSet<Employee>();

会社が更新されると、その従業員コレクションも更新される可能性があります (従業員の削除または追加) が、REST インターフェイスでは会社全体の更新しか許可されないため、従業員を明示的に削除または追加することはできません。

コレクションを単に置き換えるだけでは機能しませんが、これは機能しているように見えます。

public void setEmployees(Set<Employee> employee) {
  this.employees.clear(); // magic happens here?
  this.employees.addAll(employees);
  for (Iterator<Employee> iterator = employees.iterator(); iterator.hasNext();) {
    Employee employee = (Employee) iterator.next();
    employee.setCompany(this);
  }
} 

これはそれが行われるべき方法ですか、それともより良い方法はありますか?

編集:実際、上記は機能しません! 最初は機能しているように見えますが、次のように壊れます。

Exception in thread "main" java.lang.IllegalStateException: An entity copy was already assigned to a different entity.

データベースにはすでに従業員のセットが含まれており、「古い」従業員のいずれかが置換セットの一部でもある場合、データベース内の従業員と衝突するため、これが発生すると思います。

では、セットを交換する正しい方法は何ですか?

4

2 に答える 2

3

最初に equals が適切に実装されていることを確認してください。休止状態の仕様に従って: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch04.html#persistent-classes-equalshashcode

マージを行う際にも同様の問題がありました。基本的に、会社に関連する既存の従業員を取得する必要がありました。既存の従業員への変更をマージしてから、新しい従業員を追加する必要がありました。

    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);
        }
    }
于 2013-03-26T16:22:52.610 に答える
1

既存のコレクションを置き換えて、REST 応答によって提供される新しいコレクションを設定するよりも良い選択肢はないと思います。

于 2013-03-25T11:14:04.917 に答える