【问题标题】:Mapping of Set requires Id?Set 的映射需要 Id?
【发布时间】:2019-07-21 07:30:08
【问题描述】:

我的 spring data jdbc 有如下映射问题:
Student entity:

@Value(staticConstructor = "of")
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 @Wither
Set<StudentSubjectRegistration> studentSubjectRegistrations;
}

接下来我有一个StudentSubjectRegistration 实体:

@Value(staticConstructor = "of")
public class StudentSubjectRegistration {

@NotNull
private String electiveType;

@NotNull
private LocalDateTime created;

@NotNull
private long subjectid;
}

当我运行测试以找到一个特定的学生时,如下所示:

@Test
public void findOneStudent() throws InterruptedException, ExecutionException {
    long studentId = 2L;
    Future<Student> student = studentService.findById(2L);
    while (!student.isDone()) {
        Thread.sleep(100);
    }
    assertThat(student.get()).isNotNull();
    assertThat(student.get().getStudentId()).isEqualTo(studentId);
}

控制台说有一条sql语句发出: Executing prepared SQL statement [SELECT student.studentid AS studentid, student.userid AS userid, student.matriculationnumber AS matriculationnumber, student.email AS email FROM student WHERE student.studentid = ?]

就我的理解而言,应该发出另一个 sql 语句来获取关联的注册,不是吗?

相反,发生了异常: java.lang.IllegalStateException: Required identifier property not found for class de.thd.awp.student.StudentSubjectRegistration!

我必须用@Id 对StudentSubjectRegistration 建模吗?

StudentSubjectRegistration 不应是聚合根。它应该是来自保存其注册的Student 的引用。

我错过了什么吗?

请进一步注意我在这篇博文https://spring.io/blog/2018/09/27/what-s-new-in-spring-data-lovelace 的启发下尝试对实体不变性进行建模...

我做的对吗?

感谢您的帮助!

【问题讨论】:

  • 不可变的东西对我来说很好。

标签: java spring spring-data mapping spring-data-jdbc


【解决方案1】:

聚合中的实体需要effective-id,它在聚合中必须是唯一的。

在List 和Map 的情况下,这些是通过对聚合根和List/Map 的索引/键的反向引用来构建的。

Set 没有键、索引或类似的,因此,用@Id 注释的属性是必要的。

在你的情况下,subjectid 听起来像是一个很有前途的候选人,假设 Student 不能两次注册同一主题。

【讨论】:

  • 感谢 Jens 的帮助。我做了以下事情:private final @Id long subjectid; 在我的StudentSubjectRegistration ... 现在控制台说:Caused by: org.postgresql.util.PSQLException: Der Spaltenname studentSubjectRegistrations_subjectid wurde in diesem ResultSet nicht gefunden. ...我的命名不正确吗?
  • 这是这个错误的一个变种:jira.spring.io/projects/DATAJDBC/issues/DATAJDBC-127,其中包括破坏不可变支持。因此,您目前不能将 Set 作为构造函数参数。
  • 谢谢。我做了以下技巧来绕过这个问题:@Setter private Set&lt;StudentSubjectRegistration&gt; studentSubjectRegistrations; 在Student 实体内。
  • @ThomasLang 更好的版本是使用@Wither,因为它保持不变性。您将需要两个构造函数:一个带有所有参数。还有一个用@PersistenceContext注释的非实体。
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
相关资源
最近更新 更多