Dodawanie użytkownika do bazy danych wyjątek w aplikacji spring mvc,jdbc

0

Witam, sytuacja wygląda następująco:

Tworzę serwis webowy w springu. Stworzyłem stronę do rejestracji użytkowników. Wszystko bangla ładnie i pięknie dopóki nie spróbujemy dodać użytkownika, który już istnieje w bazie danych, ponieważ kolumna username jest kluczem głównym.

Moim celem jest obsłużenie tego wyjątku, a następnie dodanie do widoku jakieś informacji, że dana nazwa użytkownika jest już zajęta. No dobra, próbuję ale nie wychodzi:

błąd który wyskkakuje:

type Exception report

message Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO users VALUES (?,?)]; Duplicate entry 'user' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user' for key 'PRIMARY'

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO users VALUES (?,?)]; Duplicate entry 'user' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user' for key 'PRIMARY'
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
	org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:650)

Wkleję trochę kodu:

import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
import com.packt.webstore.domain.User;
import com.packt.webstore.domain.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;


@Repository

class UserRepositoryImpl implements UserRepository{

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public void addUser(User user) throws MySQLIntegrityConstraintViolationException {
        /*language=SQL*/
        String SQL_ADD_USER= "INSERT INTO users VALUES (?,?)";

        String username  = user.getUsername();
        String password  = user.getPassword();
        jdbcTemplate.update(SQL_ADD_USER, username, password);

    }
}

no to zgłosiłem, że moja metoda może spowodować bigos i w kontrolerze zamierzałem ją obsłużyć:

	@RequestMapping(value="/register", method = RequestMethod.GET)
	public String registerPage(@ModelAttribute("user") User user){return "register";}

	@RequestMapping(value="/register", method=RequestMethod.POST)
	public String processRegisterUser(@ModelAttribute("user") User user, BindingResult result){

		try {
			userRepository.addUser(user);
		} catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) {

			//tutaj jakiś kod co mi doda do widoku komuniukat, że nazwa użytkownika już jest
		}


		return "redirect:/login";
	}
}

No i to nie działa. Co mam zrobić :(?

0

Inny wyjatek (org.springframework.dao.DuplicateKeyException ?) jest prawdopodobnie rzucany.

Mysle, ze lepszym pomyslem byloby dodanie validatora ktory sprawdza czy dany uzytkownik istnieje w bazie zamiast obslugiwanie tego wyjatku. Przeczytaj o @Valid itp. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html

0

Normalnie to:
1)String nie powinien być kluczem głównym. Klucz główny to ID
2)Robisz zarządzanie transakcjami w Springu
3)Robisz obsługę wyjątku taką że jeśli zwróci błąd to wyświetlisz stosowny komunikat
Ja robiłem to zawsze z użyciem AJAXa i validowałem username i emaila przed rejestracją więc nie wiem jak to zrobić w czystym Springu MVC ale na pewno jest dużo tutoriali

0
Swr napisał(a):

Inny wyjatek (org.springframework.dao.DuplicateKeyException ?) jest prawdopodobnie rzucany.

Mysle, ze lepszym pomyslem byloby dodanie validatora ktory sprawdza czy dany uzytkownik istnieje w bazie zamiast obslugiwanie tego wyjatku. Przeczytaj o @Valid itp. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html

Zmieniłem ten wyjątek na ten co mówisz. Środowisko mi nie mówi, że mam go obsłużyć. Co jest?

Zastanawiam się jak to się robi w profesjonalnych aplikacjach.

0

Nie mówi bo to unchecked exception

0
Swr napisał(a):

Nie mówi bo to unchecked exception

To działa, jak zamieniłem te wyjątki. A skąd wiesz, że to unchecked exception? Gdzie to jest napisane?

0

W dokumentacji widać, że dziedziczy po RuntimeException: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/dao/DuplicateKeyException.html
no i IDE się nie rzucało, więc dało się domyślić.

Jakby nie było powinieneś to prawdopodobnie inaczej zrobić.

0

Trochę mieszasz, pamiętaj o wzorcu MVC - wszelka logika ma być zawarta w serwisach, których to metody wywołujemy w kontrolerach. Co do obsługi wyjątków, polecam Springowy @AdviceController - będzie on zawierać metody, których adnotacje determinują przechwycenie wyjątku - typ wyjątku bądź status http. Więcej tutaj:
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

1 użytkowników online, w tym zalogowanych: 0, gości: 1