Spring @Entity Annotation findById

时间:2017-12-08 12:06:42

标签: java spring jpa jdbctemplate

我有以下的Student实体,试图为此创建一个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),该页面会返回所有学生的JSON。但是,当我尝试@GetMapping("/api/students/{id}")并指定@PathVariable时,页面会返回一些内容,但所有字段都为空。任何人都知道问题是什么?

编辑:

@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来自从PostgreSQL数据库获取的StudentRepository。但是StudentRepository此处使用JdbcTemplate从数据库中提取而不是扩展CrudRepositoryJpaRepository,我不确定这可能是问题所在。我正在使用从我的团队传递给我的代码。这是使用findByIdResultSetExtractor的回购方法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));
}

EDIT2:

我创建了自定义StudentRowMapperStudentResultSetExtractor,现在又出现了另一个错误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吗?

EDIT3:

使用@OneToMany工作。感谢。

2 个答案:

答案 0 :(得分:1)

您的BeanPropertyRowMapper找不到字段。您在SQL中重命名它们。 所以BeanPropertyRowMapper尝试查找字段id,但您的查询返回s_id 所以学生班没有设置。

更改SQL以返回与Student类中使用的列完全相同的列名。

创建一个单独的POJO而不是Student并添加您需要的字段。检查POJO字段在SQL中是否具有相应的列名,以便正确填充。

答案 1 :(得分:1)

您已在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/