Spring @Entity注解findById
Spring @Entity Annotation findById
我有以下学生实体,正在尝试为此创建 REST API。
@Entity
public class Student {
@Id
private int id;
private String name;
private String email;
private List<Course> enrolledCourses;
public Student() {
// default constructor
}
// getters and setters
}
当使用 @RestController
时,我可以 @GetMapping("/api/students)
和页面 returns 所有学生的 JSON。但是,当我尝试 @GetMapping("/api/students/{id}")
并指定 @PathVariable
页面 returns 时,所有字段都为空。有人知道问题出在哪里吗?
编辑:
@RestController
public class StudentRestController {
@Autowired
private StudentService studentService;
@GetMapping("/api/students")
public List<Student> getAllStudents() {
return studentService.getAllStudents();
}
@GetMapping("/api/students/{id}")
public Student getStudentById(@PathVariable int id) {
return studentService.getStudentById(id);
}
}
StudentService
来自 StudentRepository
,后者来自 PostgreSQL 数据库。但是这里的 StudentRepository
使用 JdbcTemplate
从数据库中获取而不是扩展 CrudRepository
或 JpaRepository
,我不确定这是否可能是问题所在。我正在使用我的团队传给我的代码。这是 repo 方法 findById
,使用 ResultSetExtractor
和 RowMapper
.
public Student findById(int id) {
String selectSQL = "SELECT s.id as s_id, s.name as s_name, " +
"s.email as s_email, " +
"c1.id as c1_id, c1.name as c1_name, c1.alias as c1_alias, " +
"c2.id as c2_id, c2.name as c2_name, c2.alias as c2_alias," +
"c3.id as c3_id, c3.name as c3_name, c3.alias as c3_alias," +
"c4.id as c4_id, c4.name as c4_name, c4.alias as c4_alias " +
"FROM students s " +
"JOIN courses c1 ON s.course1_id = c1.id " +
"JOIN courses c2 ON s.course2_id = c2.id " +
"JOIN courses c3 ON s.course3_id = c3.id " +
"JOIN courses c4 ON s.course4_id = c4.id " +
"WHERE s.id = ?";
return (Student) jdbcTemplate.queryForObject(selectSQL, new Object[]{id},
new BeanPropertyRowMapper(Student.class));
}
编辑 2:
我创建了自定义 StudentRowMapper
和 StudentResultSetExtractor
,现在出现另一个错误,Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: student, for columns: [org.hibernate.mapping.Column(enrolled_courses)]
。我使用 @OneToMany
吗?
编辑 3:
使用 @OneToMany
有效。谢谢
您的 BeanPropertyRowMapper 找不到字段。您在 SQL 中重命名它们。
所以 BeanPropertyRowMapper 试图找到字段 id
但你的查询 returns s_id
所以学生 class.
中没有设置任何内容
将 SQL 更改为 return 与 Student class 中使用的列完全相同的列名。
创建一个单独的 POJO 而不是 Student 并添加您需要的字段。检查 POJO 字段在 SQL 中是否有相应的列名以正确填写。
您已将 sql 中的 bean 属性 属性重命名为别名,例如 s_id 用于 id,s_name 用于名称,因此您使用自定义行映射器来转换结果。
public class StudentRowMapper implements RowMapper
{
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Customer();
student.setId(rs.getInt("s_id"));
student.setName(rs.getString("s_name"));
//and so on
return student;
}
}
return (Student) jdbcTemplate.queryForObject(selectSQL, new Object[]{id},
new StudentRowMapper(Student.class));
可能是有用的文章
https://www.mkyong.com/spring/spring-jdbctemplate-querying-examples/
我有以下学生实体,正在尝试为此创建 REST API。
@Entity
public class Student {
@Id
private int id;
private String name;
private String email;
private List<Course> enrolledCourses;
public Student() {
// default constructor
}
// getters and setters
}
当使用 @RestController
时,我可以 @GetMapping("/api/students)
和页面 returns 所有学生的 JSON。但是,当我尝试 @GetMapping("/api/students/{id}")
并指定 @PathVariable
页面 returns 时,所有字段都为空。有人知道问题出在哪里吗?
编辑:
@RestController
public class StudentRestController {
@Autowired
private StudentService studentService;
@GetMapping("/api/students")
public List<Student> getAllStudents() {
return studentService.getAllStudents();
}
@GetMapping("/api/students/{id}")
public Student getStudentById(@PathVariable int id) {
return studentService.getStudentById(id);
}
}
StudentService
来自 StudentRepository
,后者来自 PostgreSQL 数据库。但是这里的 StudentRepository
使用 JdbcTemplate
从数据库中获取而不是扩展 CrudRepository
或 JpaRepository
,我不确定这是否可能是问题所在。我正在使用我的团队传给我的代码。这是 repo 方法 findById
,使用 ResultSetExtractor
和 RowMapper
.
public Student findById(int id) {
String selectSQL = "SELECT s.id as s_id, s.name as s_name, " +
"s.email as s_email, " +
"c1.id as c1_id, c1.name as c1_name, c1.alias as c1_alias, " +
"c2.id as c2_id, c2.name as c2_name, c2.alias as c2_alias," +
"c3.id as c3_id, c3.name as c3_name, c3.alias as c3_alias," +
"c4.id as c4_id, c4.name as c4_name, c4.alias as c4_alias " +
"FROM students s " +
"JOIN courses c1 ON s.course1_id = c1.id " +
"JOIN courses c2 ON s.course2_id = c2.id " +
"JOIN courses c3 ON s.course3_id = c3.id " +
"JOIN courses c4 ON s.course4_id = c4.id " +
"WHERE s.id = ?";
return (Student) jdbcTemplate.queryForObject(selectSQL, new Object[]{id},
new BeanPropertyRowMapper(Student.class));
}
编辑 2:
我创建了自定义 StudentRowMapper
和 StudentResultSetExtractor
,现在出现另一个错误,Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: student, for columns: [org.hibernate.mapping.Column(enrolled_courses)]
。我使用 @OneToMany
吗?
编辑 3:
使用 @OneToMany
有效。谢谢
您的 BeanPropertyRowMapper 找不到字段。您在 SQL 中重命名它们。
所以 BeanPropertyRowMapper 试图找到字段 id
但你的查询 returns s_id
所以学生 class.
将 SQL 更改为 return 与 Student class 中使用的列完全相同的列名。
创建一个单独的 POJO 而不是 Student 并添加您需要的字段。检查 POJO 字段在 SQL 中是否有相应的列名以正确填写。
您已将 sql 中的 bean 属性 属性重命名为别名,例如 s_id 用于 id,s_name 用于名称,因此您使用自定义行映射器来转换结果。
public class StudentRowMapper implements RowMapper
{
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Customer();
student.setId(rs.getInt("s_id"));
student.setName(rs.getString("s_name"));
//and so on
return student;
}
}
return (Student) jdbcTemplate.queryForObject(selectSQL, new Object[]{id},
new StudentRowMapper(Student.class));
可能是有用的文章 https://www.mkyong.com/spring/spring-jdbctemplate-querying-examples/