[英]OneToMany Spring Data JDBC
I want to model a OneToMany Relation with Spring Data JDBC. 我想用Spring Data JDBC建模OneToMany Relation。 I´ve read on this very useful blog https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates that you should use references when you want to model ToMany Reference:
我在这个非常有用的博客上阅读了https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates ,当你想为ToMany参考建模时你应该使用引用:
Therefore any Many-to-One and Many-to-Many relationship must be modeled by just referencing the id.
因此,任何“多对一”和“多对多”关系都必须通过引用id来建模。
So I have this scenario: 所以我有这个场景:
One Student
can have multiple Registration
. 一名
Student
可以进行多次Registration
。 And one Registration
can have exactly one Student
. 一个
Registration
只能有一个Student
。 If you delete Registration
the assigned Student
should not get deleted cascading. 如果删除
Registration
,则不应将已分配的Student
删除级联。
I ended up with this modelling: 我最终得到了这个建模:
@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<>();
}
My question is whether my modeling is correctly implemented? 我的问题是我的建模是否正确实施?
You are quoting the article talking about "Many-To-X" but you talk yourself about "X-To-Many". 你引用的文章是在谈论“很多到X”,但你会谈论“X-To-Many”。 You can model a One-To-One or a One-To-Many relationship with a direct reference, or a List/Set/Map of entities.
您可以使用直接引用或实体的列表/集/映射来建模一对一或一对多关系。
What you should avoid are bidirectional relationships. 你应该避免的是双向关系。 While you probably can make them work with the approach you are using, you really shouldn't.
虽然你可能会让它们与你正在使用的方法一起工作,但你真的不应该这样做。
Which brings us to the question: How should this model look like? 这带来了一个问题:这个模型应该怎么样?
The central decision to make is how many aggregates are involved? 做出的核心决定是涉及多少聚合?
A Student
certainly is an aggregate and the Student
class is its aggregate root. Student
肯定是一个聚合, Student
类是它的聚合根。 It can exist on its own. 它可以独立存在。
But what about Registration
? 但
Registration
呢? I'd argue, it is probably part of the same aggregate. 我认为,它可能是同一集合的一部分。 The delete test is a good one.
删除测试很好。 If you delete a
Student
from the system, do the registrations of that Student
still have value? 如果你删除一个
Student
从系统中,这样做的注册Student
还有价值吗? Or should the disappear together with the Student
? 或者应该与
Student
一起消失?
As an exercise let's do both variants. 作为练习,让我们做两种变体。 I start with: Just one aggregate:
我开始:只有一个聚合:
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<>();
}
With this, you would have a single repository: 有了这个,您将拥有一个存储库:
interface StudentRepository extends CrudRepository<Student, Long>{}
I removed all the Lombok annotations since they aren't really relevant to the problem. 我删除了所有Lombok注释,因为它们与问题无关。 Spring Data JDBC can operate on simple attributes.
Spring Data JDBC可以在简单属性上运行。
If Registration
and Student
both are aggregates it gets a little more involved: You need to decide which side owns the reference. 如果
Registration
和Student
都是聚合,则会更多地涉及:您需要决定哪一方拥有该引用。
First case: The Registration
owns the reference. 第一种情况:
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;
}
Second case: The Student
owns the reference 第二种情况:
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;
}
Note that the RegistrationRef
doesn't have a studentId
or similar. 请注意,
RegistrationRef
没有studentId
或类似的。 The table assumed for the registrations
property will have a student_id
column. 为
registrations
属性假定的表将具有student_id
列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.