删除班级时产生谬误
新增班级后删除班级时产生报错,然而单元测试时没有报错,可失常通过。
报错信息为
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!] with root cause
其中比拟要害的一句为 The given id must not be null!
。
再到网页控制台中查看报错信息为 500,确认时后盾产生的谬误。
之后再到 C 层用 logger.info()打印之后发现从前台传过来的 id 却是为 null, 之后再查看了一下单元测试中的内容
@Test
public void delete() {Teacher teacher = new Teacher();
Klass klass = new Klass();
klass.setName("测试 123123 班级");
klassRepository.save(klass);
klassService.delete(klass.getId());
Optional<Klass> klassOptional = klassRepository.findById(klass.getId());
Assertions.assertThat(klassOptional.isPresent()).isFalse();}
发现单元测试时的班级 ID 是间接调用 klass.getId()取得的 id,再回到 C 层查看发现在 delete
办法中的参数没有增加 @PathVariable
注解。单元测试并没有检测到前台数据是否传到了后盾。
这也就是说在写完后盾后要优先测试前台数据是否传送到后盾。
删除与班级绑定的老师时产生谬误
老师与班级绑定时理当不容许被删除,然而删除时前台应该做相应提醒或是连带与之绑定的班级一并删除(或者是解除绑定,即把 teacher_id 设为空),而不是报 500 谬误。
报错信息为:
Cannot delete or update a parent row: a foreign key constraint fails
在此,先尝试第二种解决办法
呈现这个报错的起因是:想要删除的数据或表与其余数据或表领有主外键关系,Mysql 规定,为了保护表构造的稳固,禁止执行该操作,即外键束缚失败。
如果咱们想强制删除能够执行以下语句:
String sql = String.format("delete from `teacher` where id = %s", id);
this.jdbcTemplate.update("SET foreign_key_checks = 0");
this.jdbcTemplate.update(sql);
this.jdbcTemplate.update("SET foreign_key_checks = 1");
进行操作后能够删除老师,然而相应班级没有被删除,在查看班级时也会产生报错。
咱们能够执行以下语句来操作该老师所属的班级
Teacher teacher = new Teacher();
teacher = this.teacherService.getById(id);
RowCallbackHandler rowCallbackHandler = new RowCallbackHandler() {
@Override
public void processRow(ResultSet resultSet) throws SQLException {Klass klass = new Klass();
klass.setTeacher(null);
klass.setName(resultSet.getString("name"));
klass.setId(resultSet.getLong("id"));
klassService.update(klass.getId(), klass);
}};
String newSql = String.format("select id, name, teacher_id from klass where teacher_id = %d", teacher.getId());
jdbcTemplate.query(newSql, rowCallbackHandler);
此时咱们再进行删除老师就会将其所属班级的老师设为空,实现老师的失常删除。
除此之外咱们还能够当咱们要删除老师时如果该老师有所属班级,咱们间接给出提醒——该老师已绑定班级,无奈进行删除来解决问题。
咱们能够在前台先查问后盾中是否存在班级与要删除的老师绑定,若存在则提醒——删除失败,存在班级与该老师绑定。
前台代码
onDelete(teacher: Teacher): void {const index = this.teachers.indexOf(teacher);
this.httpClient.get(`${this.url}haveKlass/${teacher.id}`)
.subscribe((flag) => {console.log(flag);
if (flag) {console.log('删除失败,存在班级与该老师绑定');
} else {this.httpClient.delete(`${this.url}/${teacher.id}`)
.subscribe(() => {this.teachers.splice(index, 1);
console.log('delete success');
},
error => console.log('delete error', error));
}
});
}
后盾 haveKlass 接口对应代码:
public Boolean haveKlass(Long id) {final Boolean[] flag = new Boolean[1];
flag[0] = false;
RowCallbackHandler rowCallbackHandler = new RowCallbackHandler() {
@Override
public void processRow(ResultSet resultSet) throws SQLException {flag[0] = true;
}
};
String newSql = String.format("select id, name, teacher_id from klass where teacher_id = %d", id);
jdbcTemplate.query(newSql,rowCallbackHandler);
return flag[0];
}
JAVA 中 String/Boolean… 与 string/boolean 的区别
以 boolean 为例
boolean 是 java 中最根本 8 种类型中的一种,java 为 8 中根本类型提供了封装类,用来示意一个对象。
不过在有些框架中,例如参数和值要求是对象类型,所以不能用根本类型。
boolean 是根本数据类型 Boolean 是它的封装类,和其余类一样,有属性有办法,能够 new,例如:Boolean flag = new Boolean(“true”); // boolean 则不能够!