Category: it

Category was added automatically. Read all entries about "it".

VMWare Player 6.x на Fedora 21 (kernel 3.19)

Для того, чтобы заработал vmware на ядре > 3.13 (могу путаться в показаниях, но на Ubintu 14.04 LTS относительно старое ядро, и там всё работает). Надо проделать следующие шаги:

1) Выключить UEFI-Secure boot. Здесь проблема, что инсталлятор собирает модули ядра из исходиников, и пытается их загрузить неподписанные
1.1) yum install kernel-headers kernel-devel
1.2) (Важно - у вас может несовпадать версия заголовков к ядру и запущенного ядра): yum update
2) Проследовать инструкциям из https://wiki.archlinux.org/index.php/VMware#3.17_kernels - суть проблемы: распаковать исходники vmnet в своей временной директории, пропатчить патчем из ссылки, запаковать обратно и положить в /usr/lib/vmware/modules/source.
3) Запустить vmware player, он спросит установить требуемые модули ядра- проследовать его инструкциям.

Что может неожиданно сломаться: плеер вроде выдал ошибку, но при следующем старте запускается и вроде как разрешает создать виртуалку. На старте виртуалки ругается на vmmon и падает- это значит, что у вас в UEFI (который заменил BIOS) активирован SecureBoot. Придётся его отключить, и повторить попытку запустить vmware player снова.

Hibernate и построение отчетов

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

Почему так? Причин у Hibernate две:
1. Проблема "n+1 query", обусловленная ленивой инициализацией полей one2many типа Set, когда на каждую возвращенную выборкой сущность при попытке доступа к такому полю делается новый запрос к базе. Пример: имеем 1000 направлений клиентов лаборатории, делавших в ней анализы. На каждое направление - один или несколько анализов. Например, нужно вернуть только те направления, у которых есть все сданные анализы. И направления, и анализы к ним, попадают в репорт. n+1 query мы имеем из того, что на 1 запрос по направлениям Hibernate вернет 1000 результатов, а потом еще сделает 1000 запросов по анализам. С учетом, что кроме анализов, в направлении есть еще другие поля, и наличии говно-кода, который пользуется результатами всей выборки и по желанию запрашивает еще, имеем около 1 минуты на распечатку 1 направления. Из 1000.
2. Ленивая инициализация в Hibernate, которая виновна за n+1 query, может быть принудительно выключена указанием в запросе join fetch. В таком случае Hibernate на 1000 направлений составит один большой запрос на join-х, будет очень долго думать (быстрее все-таки, чем в п. 1) - и в итоге упадет от нехватки памяти. Память в наши дни - не проблема, поставим VM 1G, пусть пользуется. Но это только для 1000 направлений. С учетом n^(скока таблиц join-м) формулы, очевидно, такое решение тоже недолговечно.

Чтобы решить задачу выполнения отчетов за линейное время, нужно отказаться от услуг Hibernate и сделать запросы на SQL - фиксированное число запросов, например 8 таблиц join-ли - сделать 8 запросов, вручную заполнить POD-сущности, которые Hibernate так замечательно автоматически заполнял, и установить связи one2many или many2one между ними. Решение простое и эффективное, но при этом некрасивое: вручную вызывать кучу set-в, при этом еще держать в уме порядок аргументов в возвращаемом SQL-запросом tuple-е- утомительно и топорно. Получаются полотнища тупого набора setProperty, и тело функции в экран уже не помещается. Нужно, чтобы как в Hibernate- сущности заполнялись неявно, при этом только явно указать, какие сущности хотим иметь в tuple-е заполненными.
В процессе выполнения фичи "оптимизация времени выполнения запроса для репорта", я за день написал велосипед - пару классов, которые позволят без излишнего геморроя, в декларативном стиле, исполнить несколько запросов с получением Set-в сущностей, затем установить связи и решить поставленную задачу- вместо 1000 минут на 1000 направлений, выгрести всю необходимую инфу за 8-20 секунд. Пока классы сырые, поэтому с выкладыванием их подожду. Накатал заметку в CodeProject, находится по адресу: http://www.codeproject.com/KB/java/RawEntitySetter.aspx.

Мне интересна информация о том, какие есть велосипеды под конкретно эту задачу, т.к. я найти не смог - потому и написал свой.