• Как записать вычисляемое поле из хранимой процедуры в transient поле Entity?

    @ads83
    По определению, поле с аннотацией @Transient будет игнорироваться ORM. В обе стороны: и в БД ничего не запишется, и из базы его не установить.

    Но можно воспользоваться доступом на уровне методов. Помимо аннотации @Column, надо поставить на геттере аннотацию @Access(AccessType.PROPERTY).
    Так как поле - вычисляемое, довольно странно видеть setCrn(Double crn) в классе. Это может смутить ORM, да и людей тоже. Я бы пошел еще дальше и переименовал getCrn так, чтобы было понятно что это вычисляемое значение.

    P.S. В современных БД есть такая вещь как (materialized) view - запрос или результат работы хранимки, к результатам которого можно обращаться как к таблице. Такой подход часто используется, у него есть определенные преимущества. Наверное, тут view будет избыточным решением, но для общего развития предлагаю посмотреть и в эту сторону.
    Ответ написан
    Комментировать
  • Как правильно заполнить многомеремный массив?

    @ads83
    В двумерном массиве "Х" - это две большие диагонали. Их заполнить можно без вложенных циклов:

    public void fillX(String[][] array) {
      for (int i=1; i<size; i++) {
        array[i][i] = "x" // главная диагональ
        array[i][size-i] = "x" // побочная диагональ
      }
    }

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

    С выводом все просто: используем во вложенном цикле print, чтобы не было перехода на новую строку, и println без параметров для начала новой строки во внешнем цикле.
    Я намеренно не пишу код, а описываю его словами, чтобы у тебя была возможность написать самому и потренироваться.
    Ответ написан
    Комментировать
  • Как построить архитектуру @Service с Spring и MongoRepository?

    @ads83
    @Service - это класс. Он может иметь много методов, и каждый контроллер будет вызывать нужный. В каждом будет делаться своя, уникальная часть, а сохраниен пойдет через общий метод. Например

    // В Андроид контроллере
    service.processAndroidLink(link)
    // В iOS контроллере
    service.processMacLink(link)
    
    // в самом сервисе будут такие методы:
    public void processAndroidLink(URL link) {
      // подготавливаем данные для записи
      URL androidLink = link;
      URL iosLink = createIosLink(link);
      URL webLink = createWebLink(link);
      var doc = prepareDocument(andriodLink, iosLink, webLink);
      save(doc);
    }
    public void processWebLink(URL link) {
      // подготавливаем данные для записи
      URL androidLink = createAndroidLink(link);
      URL iosLink = createIosLink(link);
      URL webLink = link;
      var doc = prepareDocument(andriodLink, iosLink, webLink);
      save(doc);
    }
    private void save(document) {сохраняем в MongoDB}
    }

    Понятно, что вместо URL может быть любой другой тип.

    Обрати внимание, что метод сохранения разделен с prepareDocument: так проще тестировать, у них разные области видимости и в будущем prepareDocument может быть использован кем-то еще.

    В данном случае я намеренно обошел стороной вопрос проверки существования ссылки. Возможно, ты захочешь сделать это отдельным процессом. Возможно, встроишь в processAndroidLink.
    Ответ написан
    Комментировать
  • Как протестировать сервлет?

    @ads83
    Проблема в том, что твой сервлет создает каждый раз новый dbManager. Ему пофигу, что ты там мокаешь - он создает. каждый вызов. new DBManagerService()
    Это ужас-ужас и за такое бьют линейкой по пальцам в реальном коде недопустимо

    Стандартное решение - создать поле в классе и использовать code injection, т.е. прописать аннотацию @Autowired:
    public class ConformPay extends HttpServlet {
      private static final Logger LOGGER = Logger.getLogger(ConformPay.class);
      private static final long serialVersionUID = 1L;
    
    @Autowired
    DBManager dbManager


    Потом тебе надо указать Спрингу (или аналогу), где взять компонент DBManager.
    В тесте ты указываешь, что вместо настоящего DBManager нужно использовать mock.
    ----
    Другой вариант, менее трудоемкий, но и менее распространенный - это использовать мок на геттере. Так же создаешь в сервлете поле, создаешь/инжектируешь его в конструкторе и создаешь методDBManager getDBManager() {return dBManager);}. Потом в методе `doPost` обращаешься не к полю dBManager, а дергаешь геттер: getDBManager().delPayment(dtime);
    В тесте же на своем сервлете ставишь заглушку на этот метод:
    when(conformPay.getDBManager()).thenReturn(dbManagerMock)

    Проблема в этом подходе в том, что тебе нужно не создавать заглушку для conformPay, а использовать настоящий класс с заглушкой. Почитай про метод spy(), а также почему его рекомендуют применять только в исключительных случаях.
    Ответ написан
    Комментировать
  • Как правильно запустить с задержкой ~2200 объектов, каждый из которых имеет свой эндпоинт для запроса?

    @ads83
    Метод `peek` - это промежуточная операция. Одна из особенностей в том, что такие операции - ленивые, и у тебя нет гарантии когда они выполнятся и выполнятся ли вообще.

    Подход с ExecutorPool более здоровый, но например в MarketplaceCollector я не увидел инициализацию `final ScheduledExecutorService executorService`.
    Кроме того, если у тебя консольное приложение, то когда основной поток закончится, JVM пойдет завершать все дочерние и прибьет таску, которая запланирована через 3 минуты. Убедись, что оно живет достаточно долго.

    Третий момент может быть в том, что сервис, к которому ты обращаешься, считает такое число запросов с таким интервалом избыточным и временно перестает отвечать. Это тоже требует проверки.
    Ответ написан
  • Как реализовать в Hibernate каскадное удаление зависимых сущностей (ManyToOne, OneToMany)?

    @ads83
    Насколько я помню, если в `Services` ты указал `@ManyToOne Account`, то в `Account` обязан указать `@OneToMany Services`.
    Прописывать настройки каскадности нужно только в одном классе. Вот похожий вопрос на английском.
    Ответ написан
  • Как строку перевести в математическое выражение?

    @ads83
    что делать со знаками я не знаю
    Нужно разбирать (парсить) все выражение целиком. Глобально, есть два варианта:
    1. Пойти легким путем и использовать готовые парсеры. Например, в ответе profesor08 используется встроенный в движок javascript - фунцкия eval. Она все делает сама: определяет числа, расставляет приоритет операций, считает.
    2. Пойти интересным путем и написать парсер самому. Такие задачи могут дать в конце семестра студентам профильного вуза. Парсер проходит по выражению и строит некое внутреннее представление. Потом проходит еще раз и вычисляет значение, исходя из этого представления. Чаще всего используется обратная польская нотация. Ничего сложного, но скорее всего, первый раз уйдет не один вечер чтобы написать и отладить.

    Ответ написан
    1 комментарий
  • Можете привести примеры задач, которые выполняет суперкомпьютер?

    @ads83
    В этой статье 2011 года есть табличка, сколько будут считать двухдневный прогноз погоды "обычные" 4х-ядерные Xeon`ы с 8Гб оперативки. Для сетки 301х301 точек - 10 часов. Больше размер обсчитываемой территории - больше времени. Для прогноза на 3-5 дней придется считать большую территорию, а за 10 дней нужно учитывать весь земной шар.
    Поэтому суперкомпьютеры массово используются для расчета прогнозов погоды.

    О том, какие задачи решает (относительно старый) IBM Watson, была статья на Хабре. Компании, заказавшие расчеты на нем, платили деньги за аренду. Видимо, это было дешевле чем купить "обычные" сервера или арендовать облако.
    Ответ написан
    Комментировать
  • Как приклеить строку к правому краю?

    @ads83
    При таком подходе - никак. Дело в том, что у вас текст формируется один раз, а ширина "экрана" может меняться (телефон повернули, изменили размер окна).

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

    Есть и другие варианты, но главное - код менять придется.
    Ответ написан
    Комментировать