Задать вопрос
  • Как в Spring правильно создавать и инжектить сервисы?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Степан,
    Если ответить на ваш вопрос простыми словами, то в контроллер инжектите интерфейс (и создаете сервис, который имплементирует этот сервис). А в сервис уже инжектятся другие интерфейсы и сервисы, а также репозитории и конвертеры и прочее.

    Или в сервисы можно инжектить только другие сервисы?

    Можно инжектить другие сервисы тоже. Вот, представьте что из одного сервиса вы пытаетесь вызвать метод для добавления другой сущности. Вы можете просто инжектить репозиторий другой сущности и сохранить сущность методом save, другое дело, что вы инжектите сервис для работы с этой сущностью, в котором выполняется не только сохранение, но и некая бизнес логика - например, рассылка писем, пуш уведомление, валидация и т.д.

    Сломаться может следующее (как вариант):
    circular dependencies - https://www.baeldung.com/circular-dependencies-in-...

    почти похожая ситуация может быть и на модульном уровне, когда у вас есть 2 модуля, которые зависят друг от друга и собрать подобный проект не предоставляется возможным.
  • Как добавить контакт к значению HashMap?

    azerphoenix
    @azerphoenix Куратор тега Java
    Amir Kenesbay,

    Еще вопрос, а вообще как закрепить знания на все эти темы по коллекциям, может быть есть некоторые источники?

    Конечно же есть:
    1) Роберт Лафоре - Алгоритмы и структуры данных Java (книга)
    2) Data structures & algorithms - Tim Buchalka (курс на Udemy)
    список можно продолжить дальше... в общем, ищите структуры данных и алгоритмы java и читайте статьи. Можно еще решить задачки на hackerrank и подобных сайтах
  • Как ограничить права на редактирование записей?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Nightmare058,

    Получается, в каждой записи мне нужно хранить id создателя.

    Конечно же, вам нужно связать сущности пользователь и запись. А затем, получаете пользователя и его роли и привилегии и смотрите может ли он совершать то или иное действие.
  • Как добавить контакт к значению HashMap?

    azerphoenix
    @azerphoenix Куратор тега Java
    Amir Kenesbay, как вариант, да вы можете конветировать String -> int, а затем уже сортировать.
    Вот, похожий вопрос - https://stackoverflow.com/questions/41562158/how-t...
  • Как сделать sql запрос из MySQL в TableView?

    azerphoenix
    @azerphoenix Куратор тега Java
    BaLahmuT, если вы используете Spring и при этом приложение не клиент-серверное, то воспользуйтесь возможностями ORM (Spring Data JPA).
    Долго писать примеры подключения и настройки hibernate. Я лучше дам ссылки на полезные ресурсы.

    https://spring.io/guides/gs/accessing-data-jpa/

    Если вкратце, то:
    - средствами java вы создаете сущности и связываете их друг с другом.
    - на основе вашего кода в БД создаются соответствующие таблицы
    - используя DAO (Data Access Object, Repository) вы пишете методы, которые выполняют запрос в БД и возвращают информацию. Например,
    List<User> users = userRepository.findAll();
    - а дальше вы уже отрисовываете полученный ответ из БД в таблице
  • Как добавить проверку на ввод в spring boot application?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Степан,
    Да, нужен и UserRequestDTO & UserResponseDTO.
    Вообще, лучше не отдавать на клиент всю структуру вашей БД. Для этих целей используется доп. прослойка Data To Object.
    Например, вам нужно вернуть список пользователей, но некоторые данные о пользователях хранимые в БД не нужны. В этом случае используется паттерн DTO.

    Для удобства работы с DTO (для маппинга) можно использовать ModelMapper || MapStruct. Ну или же интерфейс Converter<FROM, TO> самого спринга
  • Как в Spring правильно создавать и инжектить сервисы?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Степан,

    Но ведь не будет ошибкой такой вариант:

    Нет, это конечно же не ошибка. Другое дело, что в программировании есть различные принципы и паттерны, которых стараются придерживаться. В данном случае это GRASP
    https://habr.com/ru/post/92570/
    https://ru.wikipedia.org/wiki/GRASP

    А также собственно говоря, https://habr.com/ru/post/131993/

    Могли бы привести пример кода? Спасибо.

    1) это аннотация Primary
    https://www.baeldung.com/spring-primary
    Если у вас несколько имплементаций интерфейса, но при этом над одним из классов стоит аннотация Primary, то этот класс будет приоритетнее.
    @Component
    @Primary
    public class GeneralManager implements Manager {

    2) Аннотация Qualifier
    @Autowired
        @Qualifier("fooFormatter")
        private Formatter formatter;

    https://www.baeldung.com/spring-qualifier-annotation
    3) А также аннотации Resource & Inject
    https://www.baeldung.com/spring-annotations-resour...
  • Как правильно присвоить значение объекту в thymleaf?

    azerphoenix
    @azerphoenix Куратор тега Java
    федор unknown, Так, я глянул ваш проект.
    1) как я вижу в коде вы закомментировали отношение ManyToMany для Product & Category.

    2) Нет смысла в строке (сущ. Product)
    private String category;
    если у вас есть сущность Category

    3) В сущности Category
    @ManyToMany(mappedBy = "category")
    А должно быть:
    @ManyToMany(mappedBy = "categoryList")
    потому что в сущ. Product
    private List<Category> categoryList;

    4) Для таких полей, как private String description;
    лучше добавлять такую строку, как @Column(length=1000) Иначе по дефолту кол-во символов равно 255 и в случае, если описание больше, чем 255 символов, то получите исключение при попытке сохранить запись.

    5) Небольшой совет
    public Category get(Long id) {
            if (repository.findById(id).isPresent()){
                return repository.findById(id).get();
            }
            log.error("Категория не найдено");
            return null;
        }

    Чтобы такого не делать, лучше используйте Optional<Category>

    6) Еще один совет...
    private int price;
    int или long не подходит для хранения информации о стоимости. Вот, представьте, что если товар стоит 100 рублей 55 копеек. Это уже как минимум тип double или float.
    Гораздо правильнее использовать BigDecimal. Ну или на худой конец для учебного проекта подойдет - double.

    7) Чуть изменил ManyToMany
    Category
    @ManyToMany(mappedBy = "categoryList")
        private List<Product> productList;

    Product
    @ManyToMany(fetch = FetchType.LAZY, cascade = {
    			CascadeType.PERSIST,
    			CascadeType.MERGE
    	})
    	@JoinTable(name = "product_categories",
    				joinColumns = @JoinColumn(name = "product_id"),
    				inverseJoinColumns = @JoinColumn(name = "category_id"))
    	private List<Category> categoryList;


    8) Теперь, что касается вашего вопроса про категорию.

    Во-первых, в шаблоне вы некорректно выводите колонку категории
    <td th:text="${product.category}">Категория</td>
    По факту вы выводите private String category; вместо списка категорий. См. пункт 2 (это поле вообще не нужно). Вам нужно просто получить список категорий назначенных для данного товара, а затем при помощи th:each вывести названия этих категорий.
    Изменил эту колонку на:
    <td>
    				<span th:each="cat : ${product.categoryList}">
    					<span th:text="${cat.name}">Категория</span>&nbsp;
    				</span>
    				</td>


    9) Вот, что отправляется из фронта при сабмите формы:
    name=11&description=22&category=&price=300
    Как видите категория пустая. Пустая она потому, что:
    Также это поле в шаблоне new product лишнее <input type="text" th:field="*{category}"/> Зачем вам это поле, если есть select?

    10) Обратите внимание, что методы в интерфейсах по дефолту и так публичные.
    Соответственно, нет смысла писать модификатор доступа public
    public List<Category> search(String keyword);

    11) Обновил ProductRepository на
    @Query("SELECT p FROM Product p WHERE CONCAT(p.name, ' ', p.description, ' ', p.price) LIKE %?1%")
    	List<Product> search(String keyword);

    так как я в проекте удалил String category для Product.

    12) Вместо аннотации @RequestMapping можно использовать более специализированные. Например, GetMapping PostMapping PutMapping и т.д.

    13)
    th:value="${product.category}"
    Это не совсем верно. Вот, смотрите вы назначаете значению поля категория для нового товара - значение категории этого товара (которого не существует).

    14) Также в шаблоне new product обновил:
    <!-- Проблема! значение из option не происвается в product-->
    						<select th:field="*{categoryList}" class="form-select form-select-sm" aria-label="form-select-sm example" required>
    							<option selected value="">Выберите категорию</option>
    							<option th:each="category : ${categories}" th:value="${category.id}" th:text="${category.name}" value=""></option>
    						</select>


    Вот, результат с успешно добавленным товаром:
    DdLR1KS.png

    А вот, что убежало в бекэнд
    ji9bFMz.png

    Рекомендую прочитать вот, эту статью:
    https://vladmihalcea.com/the-best-way-to-use-the-m...

    Доп. полезная информация:
    https://stackoverflow.com/questions/50981616/thyme...
    https://www.baeldung.com/thymeleaf-list

    Вот, ваш проект с внесенными правками.
    https://github.com/hasanli-orkhan/demo
    Я не стал дорабатывать его, лишь указал на ваши ошибки и выше написал, как его можно улучшить
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927, надеюсь, что получилось)
    Небольшой совет на будущее:
    старайтесь на всеможномных уровнях делать бекапы, чтобы при необходимости можно было бы восстановить сайт. Сам когда-то был начинающим разработчиком и тоже много чего приходилось исправлять. Неплохой плагин UpdraftPlus Backup, который позволяет создавать бекапы. А также можно копии сайта заливать в облако. Например, Google Drive или еще куда-нибудь. Уж поверьте мне делая бекапы вы облегчите свою жизнь.
    Желаю вам успехов)
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927,
    теперь, найдите строку номер 1726.
    Увидите примерно такое:
    $(".wpcf7").on('wpcf7:mailsent', function(event){
    Строкой выше есть
    alert();
    Замените на
    //alert();
    или просто удалите.
    Сохраните и пробуйте заново
  • Как правильно присвоить значение объекту в thymleaf?

    azerphoenix
    @azerphoenix Куратор тега Java
    федор unknown, видимо, вы скинули не ту версию проекта.
    тут нет сущности Category

    нет, кода, который был показан в вашем вопросе.
    Например,
    List<Category> category = categoryService.getAll();
    и т.д.
  • Как удалить всплывающее окно подтвердите действие на сайте?

    В смысле у вас нет бекапа сайта даже?
    Понимаете, если бы вы работали по фтп, то достаточно нажать ctrl + z и вернуть все обратно.
    Так как вы редактируете файлы в самой админке, то история правок скорее всего не сохраняется. И судя по всему вы не знакомы с js.
    Вроде бы в кеше браузера у меня сохранен js код. Можете попробовать заменить содержимое файла common.js на этот:
    https://codeshare.io/wn4bWp
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927, ну если вы не можете вернуть обратно как было, то можете попробовать следующее. У вас наверняка, есть файлы этой темы. Найдите там этот же файл и замените содержимое на новый и все вернется на свои места.

    P.S. небольшой совет файлы редактировать нужно не из админки, а по фтп. Так в разы проще и безопаснее, особенно, когда например, редактируются рнр файлы
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927, стоп!

    я добавил код который вы скинули и после поломки удалил скрипт который вы скинули

    Внимательно прочитайте мои прежние сообщения.
    Не нужно код никуда добавлять. Этот код имеется в common.js К слову, я взял этот код именно из этого файла.

    Так вот, надо найти этот скрипт в этом файле и найти строчку alert(); и удалить или же закомментировать ее (добавить 2 слеша // ) в начале этой строки.
    После чего сохранить файл и посмотреть на результат
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927,
    Вот, код который я скинул выше
    function(event) {
      alert();
      $(".wpcf7").on('wpcf7:mailsent', function(event) {
    ......

    Вот, здесь нужно удалить
    alert();
  • Как удалить всплывающее окно подтвердите действие на сайте?

    Said927,

    И в этом js файле я нашел строчку с alert,влияет ли она на что то?

    Нет, она закомментирована.

    что мне делать с этим кодом? мне его удалить?

    Попробуйте удалить эту строчку - alert(); в файле common.js (2-я строка).
    А затем почистите кеш сайта (если он есть) и кеш браузера (если вы его не отключали) и заново оформите заказ и гляньте появляется ли alert