5

Spring Data JDBC を使用して OneToMany 関係をモデル化したいと考えています。この非常に便利なブログhttps://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregatesで、ToMany 参照をモデル化するときに参照を使用する必要があることを 読みました。

したがって、多対一および多対多の関係は、ID を参照するだけでモデル化する必要があります。

だから私はこのシナリオを持っています:
1つStudentは複数を持つことができますRegistration。そして、1 つRegistrationだけ持つことができますStudentRegistration割り当てられたものを削除しても、Studentカスケードは削除されません。
私はこのモデリングで終わった:

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class Registration {

    private final @Id
    @Wither
    long registrationId;

    @NotNull
    private String electiveType;

    @NotNull
    private LocalDateTime created = LocalDateTime.now();

    @NotNull
    private StudentRegistrationReference studentRegistrationReference;

}

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class StudentRegistrationReference {
    private long student;
    private long registration;
}

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor))
public class Student {

    private final @Id
    @Wither
    long studentId;

    @NotNull
    @Size(min = 4, max = 20)
    private String userId;

    @NotNull
    @Min(0)
    private int matriculationNumber;

    @NotNull
    @Email
    private String eMail;

    private Set<StudentRegistrationReference> studentRegistrationReferences = new HashSet<>();

}

私の質問は、モデリングが正しく実装されているかどうかです。

4

1 に答える 1

10

「Many-To-X」について話している記事を引用していますが、「X-To-Many」についてはあなた自身が語っています。直接参照、またはエンティティのリスト/セット/マップを使用して、1 対 1 または 1 対多の関係をモデル化できます。

避けるべきは双方向の関係です。おそらく使用しているアプローチでそれらを機能させることができますが、実際にはそうすべきではありません。

このモデルはどのように見えるべきか?

重要な決定事項は、関連する集計の数です。

AStudentは確かに集約であり、Studentクラスはその集約ルートです。単独で存在できます。

しかし、どうRegistrationですか?おそらく同じ集合体の一部だと思います。削除テストは良いものです。システムからを削除した場合Student、その登録にはStudentまだ価値がありますか? または一緒に消えるべきStudentですか?

演習として、両方のバリアントを実行してみましょう。私はから始めます: 1つの集計のみ:

class Registration {

    @Id private long Id;

    String electiveType;
    LocalDateTime created = LocalDateTime.now();
}

class Student {

    @Id private long Id;

    String userId;
    int matriculationNumber;
    String eMail;
    Set<Registration> registrations = new HashSet<>();
}

これにより、単一のリポジトリが作成されます。

interface StudentRepository extends CrudRepository<Student, Long>{}

Lombok アノテーションは問題とはあまり関係がないため、すべて削除しました。Spring Data JDBC は単純な属性を操作できます。

Registrationと両方が集約である場合Student、もう少し複雑になります: どちらの側が参照を所有しているかを決定する必要があります。

最初のケース:Registrationが参照を所有しています。

class Registration {

    @Id private long Id;

    String electiveType;
    LocalDateTime created = LocalDateTime.now();

    Long studentId;
}

public class Student {

    @Id private long Id;

    String userId;
    int matriculationNumber;
    String eMail;
}

2 番目のケース:Studentが参照を所有する

class Registration {

    @Id private long Id;

    String electiveType;
    LocalDateTime created = LocalDateTime.now();
}

class Student {

    @Id private long Id;

    String userId;
    int matriculationNumber;
    String eMail;

    Set<RegistrationRef> registrations = new HashSet<>();
}

class RegistrationRef {

    Long registrationId;
}

には aまたは類似のRegistrationRefものがないことに注意してください。プロパティにstudentId想定されるテーブルには、列があります。registrationsstudent_id

于 2018-11-19T15:24:14.587 に答える