Problems encountered this week

An error occurred while deleting the class

An error is reported when deleting a class after adding a class, but no error is reported during the unit test, and it can pass normally.
The error message is

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 key sentence is The given id must not be null!.
Check the error message in the web console, which is 500. The error occurred in the background when confirming.
Then go to layer C and use logger After printing info(), I found that the id passed from the foreground was null. Then I checked the content in the unit test

  @Test
    public void delete() {
        Teacher teacher = new Teacher();
        Klass klass = new Klass();
        klass.setName("Test class 123123");
        klassRepository.save(klass);
        klassService.delete(klass.getId());

        Optional<Klass> klassOptional = klassRepository.findById(klass.getId());
        Assertions.assertThat(klassOptional.isPresent()).isFalse();
    }

The class ID when the unit test is found is to directly call Klass The ID obtained by getid () returns to the C layer. It is found that the @ PathVariable annotation is not added to the parameter in the delete method. The unit test did not detect whether the foreground data was transferred to the background.
This means that after writing the background, we should give priority to testing whether the foreground data can be transmitted to the background.

An error occurred while deleting the teacher bound to the class

When a teacher is bound to a class, it should not be deleted, but when deleting, the foreground should give a corresponding prompt or delete the bound class together (or unbind, that is, set the teacher_id to null), rather than report a 500 error.
The error message is:

Cannot delete or update a parent row: a foreign key constraint fails

Here, try the second solution first
The reason for this error is that the data or table to be deleted has a primary foreign key relationship with other data or tables. Mysql stipulates that in order to maintain the stability of the table structure, this operation is prohibited, that is, the foreign key constraint fails.
If we want to force deletion, we can execute the following statement:

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");

The teacher can be deleted after the operation, but the corresponding class has not been deleted, and an error will be reported when viewing the class.
We can execute the following statement to operate the class to which the teacher belongs

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);

At this time, if we delete it again, the teacher will set the teacher of the class to be empty to realize the normal deletion of teachers.

In addition, when we want to delete a teacher, if the teacher has a class, we can give a prompt directly - the teacher has bound the class and cannot be deleted to solve the problem.

In the foreground, we can first query whether there is a class bound to the teacher to be deleted in the background. If so, we will be prompted - deletion failed, and the existing class is bound to the teacher.

Foreground code

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('Failed to delete. The existing class is bound to the teacher');
        } else {
          this.httpClient.delete(`${this.url}/${teacher.id}`)
            .subscribe(() => {
                this.teachers.splice(index, 1);
                console.log('delete success');
              },
              error => console.log('delete error', error));
        }
      });
  }

Corresponding code of background haveKlass interface:

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];
    }

string/boolean in JAVA Difference from string/boolean

Take boolean as an example
boolean is one of the eight most basic types in java. java provides encapsulated classes for the eight basic types to represent an object.

However, in some frameworks, for example, parameters and values require object types, so basic types cannot be used.

Boolean is the basic data type. Boolean is its encapsulated class. Like other classes, it has attributes and methods, and can be new. For example, Boolean flag = new Boolean ("true")// Boolean cannot!

Keywords: Java

Added by Chrisj on Fri, 21 Jan 2022 05:09:05 +0200