Java - получить имя пользователя из БД

У меня есть веб-сайт стороннего проекта, где люди могут комментировать вещи, теперь мне нужно отображать комментарии пользователей и имя пользователя комментатора. Проблема в том, что я не могу получить имя пользователя, вошедшего в систему.

Примеры комментариев:

1) Прокомментировал - Шело
Комментарий к тесту

2) Прокомментировал - ProGa
Комментарий к тесту 2

Теперь проблема в том, что если я попытаюсь получить имя пользователя «в данный момент вошедшего в систему», оба комментария будут иметь одно и то же имя пользователя, когда пользователь войдет в систему.

Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
String name = loggedInUser.getName();

В приведенном выше примере кода показано, как вы получаете пользователя, вошедшего в систему. Итак, если я использую этот код и попытаюсь отобразить имя пользователя с помощью String name, и, скажем, какой-то пользователь войдет в систему с именем пользователя — "Давос", оба комментария будут выглядеть так:

1) Прокомментировал - Давос
Комментарий к тесту

2) Прокомментировал - Давос
Комментарий к тесту 2

Что мне нужно, так это получить имя пользователя, который вошел в систему, и если он оставит комментарий, отобразить его имя пользователя. Когда он выходит из системы или какой-либо другой пользователь входит в систему, «имя пользователя» комментария должно оставаться прежним и не должно меняться в зависимости от того, кто в данный момент вошел в систему.

Моя схема базы данных

Controller Class (only relevant code):

@GetMapping("/foodDescription/{id}")
public String foodDescriptionPage(Model model, @PathVariable(name = "id") String id){
    menuRepository.findById(id).ifPresent(o -> model.addAttribute("menu", o));


    return "food-description";
}

@PostMapping("/postComment/{id}")
public String postComment(@RequestParam String myComment, Model model, @PathVariable(name = "id") String id){

    Optional<Menu> menu = menuRepository.findById(id);
    menuRepository.findById(id).ifPresent(o -> model.addAttribute("menu", o));
    List<Comments> myCommentsList = menu.get().getComments();
    myCommentsList.add(new Comments(myComment));

    menu.get().setComments(myCommentsList);
    menuRepository.save(menu.get());

    return "food-description";
}

food-description.html (Only relevant code for comments section) :

    <h3 th:text = "Comments">asd</h3>
<form th:action = "@{/postComment/{myMenuId}(myMenuId=${menu.id})}" method = "POST">
    <textarea rows = "2" cols = "100" name = "myComment"></textarea>
    <input type = "submit" th:value = "Add"/>
</form>

<div class = "comment" th:each = "com : ${menu.comments}">
    <h3 th:text = "Display Commenter's Username here">Commenter's Username</h3>
    <ul>
        <li th:text = "${com.comment}">Comment</li>
    </ul>
</div>

User entity :

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "username")
    private String userName;

    @Column(name = "password")
    private String password;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinTable(name = "users_role",
    joinColumns = @JoinColumn(name = "user_id"),
    inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Role role;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinTable(name = "users_comments",
    joinColumns = @JoinColumn(name = "user_id"),
    inverseJoinColumns = @JoinColumn(name = "comment_id"))
    private List<Comments> comments = new ArrayList<>();

    // Getters/Setters/Constructor

}

Comment entity :

@Entity
@Table(name = "comments")
public class Comments {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "comment")
    private String comment;

    // Getters/Setters/Constructor

Это основа моделирования. Вам нужно добавить ссылку на author комментария, добавив свойство userId к сущности comment. Затем, когда вам нужно отобразить имя автора, вы запрашиваете его из БД.

Mạnh Quyết Nguyễn 22.02.2019 11:09

То, что сказал Мань, верно. У вас уже есть отношение @OneToMany от User к Comments, все, что вам нужно, это добавить отношение @ManyToOne от Comments к User.

kscherrer 22.02.2019 11:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
112
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминалось в комментариях, вы должны изменить свое моделирование данных.

Например, вы можете реализовать что-то вроде этого:

@Entity
public class User {
   @OneToMany()
   public Collection<Comment> comments;
   ...
}

@Entity
public class Comment {
   @ManyToOne
   @JoinColumn(name = "user_fk")
   public User user;
   ...
}

В этом случае у вас есть двунаправленная ассоциация, и вы можете получить комментарий пользователя в коде (и в шаблоне html). Конечно, вы также должны изменить свою модель БД, если вы делаете это вручную.

Поэтому я добавил ассоциацию @ManyToOne, и после создания comment она правильно добавляется в БД. Но когда я пытаюсь получить доступ к user комментария с помощью - comment.getUser().getUserName() - я получаю исключение nullPointerException

Tornike 22.02.2019 12:22

И зачем мне менять модель БД?

Tornike 22.02.2019 12:22

есть ли столбец user_fk в таблице комментариев в вашей базе данных?

MPhil 22.02.2019 12:23

Да . У меня есть ассоциация с User->user_role->roleMenu->menu_ingredient->ingredientsMenu->menu_comments->commentsUser->user_comments->comments

Tornike 22.02.2019 12:49

Я думаю, что нашел правильный путь получения имени пользователя, я дам вам знать :)

Tornike 22.02.2019 12:51

Хорошо, я это сделал :)) Итак, во-первых, после распечатки всех пользователей с -> system.out.println(comment.getUser()); я обнаружил, что действительно странно, что некоторые выходные данные, где null, а некоторые были нормальными, поэтому я решил, что мне нужно обрезать мои таблицы, потому что null выходные данные были на старых записях (которые были добавлены до создания двунаправленной ассоциации).

Tornike 22.02.2019 13:03

После усечения таблиц и создания новых записей я смог вывести username в тимелеафе с помощью <h3 th:text = ${com.user.userName}></h3> . Если у кого-то есть такая же проблема, имейте в виду, что у меня уже есть родительский цикл, где я использую com в качестве переменной, поэтому вы можете использовать только - ${comment.user.userName}, основная вещь заключается в том, что вам нужно пройти через comment, чтобы найти user, а затем перебрать user, чтобы найти поле userName. :)

Tornike 22.02.2019 13:07

Другие вопросы по теме