2

I develop a "school electronic diary" app and now I'm trying to create a method that will add students to class. But here I faced with the problem. When I try to add the entity to list of entity - nothing is happening.

So here is controller which receives my requests:

@RestController
@RequestMapping("/api/admin/class")
public class AdminClassController {
    @Autowired
    private AdminService adminService;

    @Autowired
    private ClassService classService;

    @PostMapping("/user")
    public ResponseEntity<Object> addUserToClass(@RequestBody AdminAddUserToClassModel userAndClassData) {
        try {
            return ResponseEntity.ok(adminService.addUserToClass(userAndClassData));
        } catch (UserNotFoundException | ClassNotFoundException e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
        } catch (UserAlreadyExistsException e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
        }
    }
}

Here's the AdminService

@Service
public class AdminService {
    @Autowired
    private UserService userService;

    @Autowired
    private UserRepository userRepo;

    @Autowired
    private SchoolRepository schoolRepo;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private ClassService classService;

    @Autowired
    private ClassRepository classRepo;

    public ClassEntity addUserToClass(AdminAddUserToClassModel userAndClassModel)
            throws UserNotFoundException, ClassNotFoundException, UserAlreadyExistsException {
        UserEntity user = userService.getUserEntity(userAndClassModel.getUserId());
        ClassEntity schoolClass = classService.getClassEntity(userAndClassModel.getClassId());
        if(schoolClass.getStudents().contains(user)) {
            throw new UserAlreadyExistsException("user already in this class");
        }
        schoolClass.getStudents().add(user);
        classRepo.save(schoolClass);
        userRepo.save(user);
        return schoolClass;
    }
}

And in the addUserToClass method, when I try to add user to ClassEntity and try to save it, nothing is happening!

Here's the getUserEntity method of UserService

public UserEntity getUserEntity(long userId) throws UserNotFoundException {
        return userRepo.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("user with id " + userId + " not found"));
    }

And getClassEntity of ClassService

public ClassEntity getClassEntity(long classId) throws ClassNotFoundException {
        return classRepo.findById(classId)
                .orElseThrow(() -> new ClassNotFoundException("class with such id doesn't exists"));
    }

And,of cource, entities:

UserEntity

@Entity
@Table(name = "users", schema = "working_schema")
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Getter @Setter
    private long id;

    @Getter @Setter
    private String login;

    @Getter @Setter
    private String password;

    @Getter @Setter
    private String phoneNumber;

    @Getter @Setter
    private String email;

    @Getter @Setter
    private String name;

    @Getter @Setter
    private String surname;

    @Getter @Setter
    private String patronymic;

    @ManyToOne
    @JoinColumn(name = "roleid", nullable = false)
    @Getter @Setter
    private RoleEntity role;

    @ManyToOne
    @JoinColumn(name = "classid")
    @Getter @Setter
    private ClassEntity userClass;

    @ManyToOne
    @JoinColumn(name = "schoolid")
    @Getter @Setter
    private SchoolEntity school;


    public UserEntity() {
    }
}

ClassEntity

@Entity
@Table(name = "classes", schema = "working_schema")
public class ClassEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Getter @Setter
    private long id;

    @Getter @Setter
    private int number;

    @Getter @Setter
    private char letter;

    @OneToMany(mappedBy = "userClass", cascade = CascadeType.ALL)
    @Getter @Setter
    @JsonIgnore
    private List<UserEntity> students;

    @ManyToOne
    @JoinColumn(name = "schoolid")
    @Getter @Setter
    private SchoolEntity school;

    @OneToOne
    @JoinColumn(name = "timetableid")
    @JsonIgnore @Getter
    @Setter
    private TimetableEntity timetable;

    public ClassEntity() {
    }
}

SchoolEntity

@Entity
@Table(name = "schools", schema = "working_schema")
public class SchoolEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Getter @Setter
    private long id;

    @Getter @Setter
    private long number;

    @OneToMany(mappedBy = "school", cascade = CascadeType.ALL)
    @Getter @Setter
    @JsonIgnore
    private List<UserEntity> students;

    @OneToMany(mappedBy = "school", cascade = CascadeType.ALL)
    @Getter @Setter
    @JsonIgnore
    private List<ClassEntity> classes;
}

So if you know what can be a problem, please tell me, I'd really appreciate it!

UPDATE

Here's SQL queries:

Hibernate: 
    select
        classentit0_.id as id1_0_0_,
        classentit0_.letter as letter2_0_0_,
        classentit0_.number as number3_0_0_,
        classentit0_.schoolid as schoolid4_0_0_,
        classentit0_.timetableid as timetabl5_0_0_,
        schoolenti1_.id as id1_2_1_,
        schoolenti1_.number as number2_2_1_,
        timetablee2_.id as id1_4_2_ 
    from
        working_schema.classes classentit0_ 
    left outer join
        working_schema.schools schoolenti1_ 
            on classentit0_.schoolid=schoolenti1_.id 
    left outer join
        working_schema.timetables timetablee2_ 
            on classentit0_.timetableid=timetablee2_.id 
    where
        classentit0_.id=?
Cross
  • 497
  • 1
  • 3
  • 13

1 Answers1

0

Leaving this here for reference for others, but the Question is NOT solved.

In AdminService your method:

public ClassEntity addUserToClass(AdminAddUserToClassModel userAndClassModel)
            throws UserNotFoundException, ClassNotFoundException, UserAlreadyExistsException {
        UserEntity user = userService.getUserEntity(userAndClassModel.getUserId());
        ClassEntity schoolClass = classService.getClassEntity(userAndClassModel.getClassId());
        if(schoolClass.getStudents().contains(user)) {
            throw new UserAlreadyExistsException("user already in this class");
        }
        schoolClass.getStudents().add(user);
        classRepo.save(schoolClass);
        userRepo.save(user);
        return schoolClass;
    }

Does not indicate that it is a Transactional method: https://www.baeldung.com/transaction-configuration-with-jpa-and-spring

While you call save, it is not performing a commit. Similarly to how in some SQL languages you can perform inserts, updates, deletes, and if you do not commit the result will not be present on your additional queries.

So change your ClassEntity to have @Transactional on top of it, which will cause a commit to occur at the end of the method.

Additionally ensure you enable TransactionManagement somewhere in your configuration

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

}
TedEllis
  • 66
  • 6
  • doesn't ```@Service``` annotation provide a transactional methods? I have a method that do completely the same but with another entity, and it works. – Cross Oct 04 '22 at 18:40
  • There is some good detail on this in this stackoverflow: https://stackoverflow.com/questions/50833029/is-spring-service-transactional You may also try a saveAndFlush, if you prefer, which I believe should rule out any other issues. – TedEllis Oct 04 '22 at 18:42
  • Well, ok, I got it. But I added ```@Transactional``` annotation to service class and added the class that you wrote, but it's still not working :( – Cross Oct 04 '22 at 18:54
  • Hmm, can we check that the sql you are expecting is being run? In your application.properties `spring.jpa.show-sql=true` `spring.jpa.properties.hibernate.format_sql=true` Should show you the queries – TedEllis Oct 04 '22 at 19:12
  • I updated my question with sql queries – Cross Oct 04 '22 at 19:23
  • I see your update however it is only showing a single select, are you certain that select is coming from the addUserToClass method, as I would expect it to produce multiple update statements – TedEllis Oct 04 '22 at 19:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/248550/discussion-between-tedellis-and-cross). – TedEllis Oct 04 '22 at 19:29