1

私のプロジェクトでは、双方向の多対多の関係を持つ2つのエンティティが必要です。ただし、結合テーブルには他のテーブルとの独自の追加の関係が必要であるため、結合テーブルの新しいエンティティを自分で作成しました。

次のようになります。

プロジェクト-InspectorAssignment-ユーザー

インスペクターの割り当てをプロジェクトに追加して永続化する場合は、割り当ても永続化する必要があり、ユーザーにも割り当てを追加する必要があります。

これを行うために、サービスにメソッドがあります。

projectService.assignInspectorToProject(inspector, project);

ただし、このメソッドを2回実行すると、テーブルに2つのレコードが作成されます。すべてのコレクションがセットであるため、これは発生しないはずです。

誰かが私が間違っていることを指摘できますか?

関連するすべてのメソッド/クラス:

ProjectService

public void assignInspectorToProject(User user, Project project) {

    if (!user.hasRole("inspector")) {
        throw new RuntimeException("This user is no inspector");
    }

    project.addInspector(user);
    projectDao.save(project);
}

計画

@Entity
public class Project extends AbstractPersistentObject {

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "project")
    private Set<InspectorAssignment> inspectorAssignments;  

    public void addInspector(User user) {

        InspectorAssignment assignment = new InspectorAssignment(user, this);
        user.addInspectorAssignment(assignment);

        inspectorAssignments.add(assignment);
    }
}

InspectorAssignment

@Entity
public class InspectorAssignment extends AbstractPersistentObject {

    @ManyToOne
    @NotNull
    private User user;

    @ManyToOne
    @NotNull
    private Project project;

    public InspectorAssignment() {
    }

    public InspectorAssignment(User user, Project project) {
        setUser(user);
        setProject(project);
    }
}

ユーザー

@Entity
public class User extends AbstractPersistentObject implements UserDetails {

     @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL})
     private Set<InspectorAssignment> inspectorAssignments;

     public void addInspectorAssignment(InspectorAssignment assignment) {
         inspectorAssignments.add(assignment);
     }
}
}

AbstractPersistenObjectのequalsおよびhashcodeメソッド(すべてのエンティティが拡張するクラス)

 @Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    AbstractPersistentObject other = (AbstractPersistentObject) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (id.equals(other.id))
        return true;
    return false;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}
4

1 に答える 1

2

それは私にはかなり論理的に思えます。このメソッドを2回呼び出します。したがって、InspectorAssignmentの2つの異なるインスタンスを作成し、両方を保存します。プロジェクトを保存して保存した場合でも、プロジェクトには、InspectorAssignmentの2つの異なるインスタンスを含む一連の割り当てがあります。hashCode()セットは、最初のセットと同じである場合、2番目のセットを追加しませんが、オーバーライドしていないため、追加されませんequals()

私は...するだろう

  • 割り当てテーブルに一意の制約を作成して、userId-projectIdこれが発生しないようにし、代わりに例外をスローします
  • 新しいInspectorAssignmentがまだ存在しない場合にのみ作成します
  • ProjectからInspectorAssignmentへのカスケードを頼りにするのではなく、明示的に保存してInspectorAssignmentをデータベースに作成します
  • オーバーライドequals()およびhashCode()InspectorAssignment
于 2012-05-19T15:05:37.913 に答える