=== Напредни апликативен развој (Трансакции, Pooling) === == Трансакции == Зошто ни се потребни трансакции? При креирање на корисници, како што се благајник, родител, наставник, записот мора да биде запишан прво во наткласата Корисник а потоа во поткласите. Овој процес мора да биде конзистентен и да се изврши без прекини. Затоа при креирање на овие корисници ја користиме анотацијата **@Transactional**. Оваа анотација се користи за да му се каже на Spring Boot автоматски да се грижи за COMMIT и ROLLBACK кој може да се случи доколку настане некоја грешка. = Креирање на благајник = {{{ @Value("${wallet.receiver}") private String metamusk_adresa; @Override @Transactional public BlagajnikResponseDTO createBlagajnik(BlagajnikRequestDTO blagajnikRequestDTO) { System.out.println("Пристигнат DTO: " + blagajnikRequestDTO); if(blagajnikRequestDTO.getE_posta() == null || blagajnikRequestDTO.getE_posta().isEmpty() || blagajnikRequestDTO.getLozinka() == null || blagajnikRequestDTO.getLozinka().isEmpty() || blagajnikRequestDTO.getIme() == null || blagajnikRequestDTO.getIme().isEmpty() || blagajnikRequestDTO.getPrezime() == null || blagajnikRequestDTO.getPrezime().isEmpty() || blagajnikRequestDTO.getPol() == null || blagajnikRequestDTO.getPol().isEmpty() || blagajnikRequestDTO.getAdresa() == null || blagajnikRequestDTO.getAdresa().isEmpty() || blagajnikRequestDTO.getKreiranOdId() == null ){ throw new IllegalArgumentException("invalid blagajnik data"); } String encodedPass = passwordEncoder.encode( blagajnikRequestDTO.getLozinka()); this.direktorAdminService.getDirektorAdminById(blagajnikRequestDTO.getKreiranOdId()); KorisnikRequestDTO korisnikDto = new KorisnikRequestDTO( blagajnikRequestDTO.getE_posta(), encodedPass, blagajnikRequestDTO.getIme(), blagajnikRequestDTO.getPrezime(), blagajnikRequestDTO.getPol(), blagajnikRequestDTO.getAdresa(), blagajnikRequestDTO.getKreiranOdId() ); KorisnikResponseDTO korisnik = korisnikService.createKorisnik(korisnikDto); UUID korisnikId = korisnik.getId(); this.blagajnikRepository.createBlagajnik(korisnikId,metamusk_adresa, true); BlagajnikResponseDTO blagajnikResponseDTO = this.getBlagajnikById(korisnikId); return blagajnikResponseDTO; } }}} = Креирање на наставник = {{{ @Override @Transactional public NastavnikResponseDTO createNastavnik(NastavnikRequestDTO dto) { if (dto.getE_posta() == null || dto.getE_posta().isEmpty() || dto.getLozinka() == null || dto.getLozinka().isEmpty() || dto.getIme() == null || dto.getIme().isEmpty() || dto.getPrezime() == null || dto.getPrezime().isEmpty() || dto.getPol() == null || dto.getPol().isEmpty() || dto.getAdresa() == null || dto.getAdresa().isEmpty() || dto.getKreiranOdId() == null) { throw new IllegalArgumentException("Invalid nastavnik data"); } String encodedPass = passwordEncoder.encode( dto.getLozinka()); direktorAdminService.getDirektorAdminById(dto.getKreiranOdId()); KorisnikRequestDTO korisnikDto = new KorisnikRequestDTO( dto.getE_posta(), encodedPass, dto.getIme(), dto.getPrezime(), dto.getPol(), dto.getAdresa(), dto.getKreiranOdId() ); KorisnikResponseDTO korisnik = korisnikService.createKorisnik(korisnikDto); UUID korisnikId = korisnik.getId(); this.nastavnikRepository.createNastavnik(korisnikId, true); NastavnikResponseDTO nastavnikResponseDTO = this.getNastavnikById(korisnikId); return nastavnikResponseDTO; } }}} = Креирање на родител= {{{ @Override @Transactional public RoditelResponseDTO createRoditel(RoditelRequestDTO roditelRequestDTO) { String encodedPass = passwordEncoder.encode( roditelRequestDTO.getLozinka()); this.direktorAdminService.getDirektorAdminById(roditelRequestDTO.getKreiranOdId()); KorisnikRequestDTO korisnikDto = new KorisnikRequestDTO( roditelRequestDTO.getE_posta(), encodedPass, roditelRequestDTO.getIme(), roditelRequestDTO.getPrezime(), roditelRequestDTO.getPol(), roditelRequestDTO.getAdresa(), roditelRequestDTO.getKreiranOdId() ); KorisnikResponseDTO korisnik = korisnikService.createKorisnik(korisnikDto); UUID korisnikId = korisnik.getId(); String metamusk = "SET LATER"; this.roditelRepository.createRoditel(korisnikId,true,metamusk); RoditelResponseDTO roditelResponseDTO = this.roditelRepository.findRoditelById(korisnikId); return roditelResponseDTO; } }}} Истото го имаме и кај оценките, односно според дијаграмот наткласа за усна, писмена и крајна оценка е табелата Ocenka. Затоа, за да немаме случај како што е оценката постои во табелата Ocenka, но не постои во Usna_Ocenka, Pismena_Ocenka, Krajna_Ocenka, треба да користиме трансакција. = Внесување на усна оценка = {{{ @Override @Transactional public void enterUsnaOcenkaForStudent(UUID ucenikId, FullUsnaOcenkaRequestDTO fullUsnaOcenkaRequestDTO) { if (ucenikId == null) { throw new IllegalArgumentException("ucenikId is null"); } if (fullUsnaOcenkaRequestDTO == null) { throw new IllegalArgumentException("Request is null"); } if (fullUsnaOcenkaRequestDTO.getOcenka() == null || fullUsnaOcenkaRequestDTO.getOcenka() < 1 || fullUsnaOcenkaRequestDTO.getOcenka() > 5) { throw new IllegalArgumentException("Invalid ocenka"); } if (fullUsnaOcenkaRequestDTO.getOsvoeni_poeni() > fullUsnaOcenkaRequestDTO.getMax_poeni()) { throw new IllegalArgumentException("Invalid points"); } UcenikResponseDTO ucenik = this.ucenikService.getUcenikById(ucenikId); if (ucenik == null) { throw new IllegalArgumentException("Ucenik not found"); } this.ocenkaRepository.createOcenka(fullUsnaOcenkaRequestDTO.getOcenka(), fullUsnaOcenkaRequestDTO.getDatum(), fullUsnaOcenkaRequestDTO.getZabeleska(), fullUsnaOcenkaRequestDTO.getVnesena_Od(), fullUsnaOcenkaRequestDTO.getDobienaZaUcenikot_Id(), fullUsnaOcenkaRequestDTO.getEZaPredmetot_Id(), fullUsnaOcenkaRequestDTO.getZaAktivnosta_id()); //insert in usna ocenka UUID insertedId = this.ocenkaRepository.getOcenkaByUcenikAndAktivnost(fullUsnaOcenkaRequestDTO.getDobienaZaUcenikot_Id(), fullUsnaOcenkaRequestDTO.getZaAktivnosta_id()); this.usnaOcenkaRepository.insertUsnaOcenka(insertedId, fullUsnaOcenkaRequestDTO.getTema(), fullUsnaOcenkaRequestDTO.getOsvoeni_poeni(), fullUsnaOcenkaRequestDTO.getMax_poeni(), String.valueOf(fullUsnaOcenkaRequestDTO.getVidUsnoIsprasuvanje())); } }}} = Внесување на писмена оценка = {{{ @Override @Transactional public void enterPismenaOcenkaForStudent(UUID id, FullPismenaOcenkaRequestDTO fullPismenaOcenkaRequestDTO) { if (id == null) { throw new IllegalArgumentException("ucenikId is null"); } if (fullPismenaOcenkaRequestDTO == null) { throw new IllegalArgumentException("Request is null"); } if (fullPismenaOcenkaRequestDTO.getOcenka() == null || fullPismenaOcenkaRequestDTO.getOcenka() < 1 || fullPismenaOcenkaRequestDTO.getOcenka() > 5) { throw new IllegalArgumentException("Invalid ocenka"); } if (fullPismenaOcenkaRequestDTO.getOsvoeni_poeni() > fullPismenaOcenkaRequestDTO.getMax_poeni()) { throw new IllegalArgumentException("Invalid points"); } UcenikResponseDTO ucenik = this.ucenikService.getUcenikById(id); if (ucenik == null) { throw new IllegalArgumentException("Ucenik not found"); } this.ocenkaRepository.createOcenka(fullPismenaOcenkaRequestDTO.getOcenka(), fullPismenaOcenkaRequestDTO.getDatum(), fullPismenaOcenkaRequestDTO.getZabeleska(), fullPismenaOcenkaRequestDTO.getVnesena_Od(), fullPismenaOcenkaRequestDTO.getDobienaZaUcenikot_Id(), fullPismenaOcenkaRequestDTO.getEZaPredmetot_Id(), fullPismenaOcenkaRequestDTO.getZaAktivnosta_id()); //insert in pismenaocenka UUID insertedId = this.ocenkaRepository.getOcenkaByUcenikAndAktivnost(fullPismenaOcenkaRequestDTO.getDobienaZaUcenikot_Id(), fullPismenaOcenkaRequestDTO.getZaAktivnosta_id()); this.pismenaOcenkaRepository.insertPismenaOcenka(insertedId, fullPismenaOcenkaRequestDTO.getTema(), fullPismenaOcenkaRequestDTO.getOsvoeni_poeni(), fullPismenaOcenkaRequestDTO.getMax_poeni(), String.valueOf(fullPismenaOcenkaRequestDTO.getVid())); } }}} = Внесување на крајна оценка = {{{ @Override @Transactional public void enterKrajnaOcenkaForStudent(UUID id, FullKrajnaOcenkaRequestDTO fullKrajnaOcenkaRequestDTO) { if (id == null) { throw new IllegalArgumentException("ucenikId is null"); } if (fullKrajnaOcenkaRequestDTO == null) { throw new IllegalArgumentException("Request is null"); } if (fullKrajnaOcenkaRequestDTO.getOcenka() == null || fullKrajnaOcenkaRequestDTO.getOcenka() < 1 || fullKrajnaOcenkaRequestDTO.getOcenka() > 5) { throw new IllegalArgumentException("Invalid ocenka"); } UcenikResponseDTO ucenik = this.ucenikService.getUcenikById(id); if (ucenik == null) { throw new IllegalArgumentException("Ucenik not found"); } UUID ocenkaId = UUID.randomUUID(); this.ocenkaRepository.createOcenkaWithId(ocenkaId, fullKrajnaOcenkaRequestDTO.getOcenka(), fullKrajnaOcenkaRequestDTO.getDatum(), fullKrajnaOcenkaRequestDTO.getZabeleska(), fullKrajnaOcenkaRequestDTO.getVnesena_Od(), fullKrajnaOcenkaRequestDTO.getDobienaZaUcenikot_Id(), fullKrajnaOcenkaRequestDTO.getEZaPredmetot_Id() ); this.krajnaOcenkaRepository.createKrajnaOcenka(ocenkaId, String.valueOf(fullKrajnaOcenkaRequestDTO.getTip())); } }}}