Update Roli użytkownika.

0

Witam. Tworzę od pewnego czasu aplikację i posiadam konto administratora, który zarządza użytkownikami aplikacji (blokuje, usuwa i zmienia ich rolę). Wszystko działa oprócz zmiany roli. Encja User i Role są w relacji many-to-many. Posiadam metodę, która zmienia status użytkownika i rolę, jednak nie jestem pewny do końca gdzie tkwi problem. Debugowałem i wyglądało na to, że jest okej jednak trochę się zagubiłem. Wszystko mam podpiętę do guzika na froncie (Thymeleaf). Z góry dzięki za jakieś znalezienie błędu bądź wytłumaczenie.

Metoda zmieniająca rolę

@Transactional
    public void changeUserStatus(long id, EditUserStatusDto editUserStatusDto) {//shift f6
        Optional<User> userOptional = userRepository.findById(id);
        if (userOptional.isPresent()) {
            User user = userOptional.get();
            user.setBlocked(editUserStatusDto.isBlocked());

           Role role = roleRepository.findById(id);
            user.addRole(role);
            role.setUsers(role.getUser());
        }

    }
        }

Metoda pomocnicza, dodająca po obu stronach relacji daną encję


 public void addRole(Role role){
        this.roles.add(role);
        role.getUser().add(this);
    }

Metoda w kontrolerze:


   @GetMapping("/changeUserStatus/{id}")
    public String changeUserStatus(
            @PathVariable(name = "id") long id,
            @Valid @ModelAttribute("userStatus") EditUserStatusDto editUserStatusDto,
           BindingResult result
    ){

        userServiceImpl.changeUserStatus(id, editUserStatusDto);
        return "privileges";
    }

Widok Themeleafa odpowiedzialny za zarządzanie uzytkownikami.


<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="ISO-8859-1">
    <title>Privileges</title>
    <link rel="stylesheet" th:href="@{/css/style.css}"/>
</head>
<body>
<main>
    <div class="pos-center">
        <form action="#" th:action="@{'/changeUserStatus/' + ${user.id}}" method="get">
        <style type="text/css">
            .table {
                margin: 0 auto;
                width: 50%;
                margin-top: 30px;
                margin-bottom: 30px;
            }
        </style>
        <div th:include="heading"></div>
        <table class="table table-bordered">
            <thead>
            <tr>
                <th class="text-center">First Name</th>
                <th class="text-center">Last Name</th>
                <th class="text-center">Email</th>
                <th class="text-center">Blocked</th>
                <th class="text-center">Role</th>

            </tr>
            </thead>
            <tbody>
                <td th:text="${user.firstName}">First Name</td>
                <td th:text="${user.lastName}">Last Name</td>
                <td th:text="${user.email}">Email</td>
                <td>
                    <select  th:field="*{user.blocked}">
                        <option th:value="'True'" th:text="${user.blocked}"></option>
                        <option th:value="'False'" th:text="False"></option>
                    </select>
                </td>

                <td>

                    <select th:field="*{user.roles}">
                        <option th:value="1" th:text="ADMIN"></option>
                        <option th:value="2" th:text="USER"></option>
                        <option value="3" th:text="DATAADMIN"></option>
                    </select>

                </td>
                </tr>
            </tbody>
        </table>

        <div class="container">
            <div class="center">
                <button type="submit" class="btn btn-outline-primary">Save</button>
            </div>
        </div>
        </form>
        <div th:include="footer"></div>

    </div>
</main>
</body>
</html>



1

Nie powinieneś zapisać zmiany statusu usera do repozytorium?

0

Próbowałem i nic to nie daje. Zastanawiam się właśnie czy roli nie powinienem szukać po innym id niż użytkownika.

1

No to zrób breakpoint na 10 linijce w changeUserStatus i sprawdź co dostajesz w Role. Nie wiem w jaki sposób mu nadajesz ID bo tego nie pokazałeś, ale jeśli nie wiesz po jakim ID szukać to pewnie zrobiłeś by sam się generował, wtedy szukanie roli po ID usera nie ma sensu. To jest JpaRepository? Wtedy byś mógł dodać nową metodę w interfejsie typu findByUser_id(long userId)

0

Tak, id user;'a generowane jest automatycznie. Tak JpaRepository. Ogólnie podczas tworzenia użytkownika z automatu dostaje rolę jako USER. Teraz zmieniłem trochę kod i poprzez Dto stworzone na rzecz Roli staram się zmienić tą nazwę, jednak przypisuje null'a jako rolę danego użytkownika. W debugerze widać, że meotda getRoleName zwraca null'a i dlatego tak jest.

Dto


public class EditUserStatusDto {

    private String roleName;
    private boolean blocked;
    private Set<User> users = new HashSet<>();


    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public boolean isBlocked() {
        return blocked;
    }

    public void setBlocked(boolean blocked) {
        this.blocked = blocked;
    }

    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }

Zmieniona metoda:

 @Transactional
    public void changeUserStatus(long id, EditUserStatusDto editUserStatusDto) {//shift f6
        Optional<User> userOptional = userRepository.findById(id);
        if (userOptional.isPresent()) {
            User user = userOptional.get();
            user.setBlocked(editUserStatusDto.isBlocked());


            Role role = roleRepository.findById(id);
            role.setRoleName(editUserStatusDto.getRoleName());
            user.addRole(role);

        }

    }

Wiem, że metoda nie zwróci null'a jeżeli przypiszę do pola roleName jakiejś roli, jednak w takim przypadku będzie zmieniać zawsze na taką samą rolę.

1

Tak jak wcześniej pisałeś, ta metoda:

Role role = roleRepository.findById(id);

zwróci ci nulla, bo próbujesz znaleźć rolę po ID użytkownika. Musisz ją zmodyfikować tak, aby zwróciła ci rolę po np. nazwie, skoro nazwę przekazujesz

Role role = roleRepository.findByRoleName(editUserStatusDto.getRoleName());

Pomijająm kwestie zwracania Optionala przez repozytorium, które wydaje sie byc lepszym rozwiązaniem

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