Persistence не работает в многопоточном режиме?

https://doc.cuba-platform.com/manual-7.2-ru/transactions_prog.html

Если это поместить в поток, то при первом же обращении получаем NullPointerException

Image 2022-10-14011

Есть ли какие-то рецепты лечения?

Суть задачи - загрузка в базу большого объёма данных. При загрузке одной основной сущности создаётся много второстепенных и справочных значений. Если что-то пойдёт не так, то что бы не плодить в базе кучу ненужных “огрызков”, обрамляем всё это в транзакцию. А чтобы уложиться в приемлемые сроки, есть идея использовать многопоточную обработку. Но что-то не получается…

Все должно работать в вашем коде. Наверное, какая-то глупая ошибка.

Пример кода, работающего с многопоточностью и в Persistence - см. класс Emailer

Единственный момент, у вас не получится распараллелить транзакцию. Транзакция привязана к потоку исполнения, у других потоков исполнения должны быть отдельные транзакции. Кроме того, не рекомендуется передавать сущности в managed состоянии в другой поток, могут быть глюки.

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

@Inject
protected Persistence persistence;

Он не может создать новую копию объекта и пытается в каждом потоке использовать один и тот-же бин/синглтон. А это наверное неправильно. Можно ли создать инстанс Persistence без инжекта, через какой-нибудь конструктор? И Metadata наверное тоже…

Через цепочку EmailSendTask#run() → Emailer#sendSendingMessage() → Emaailer#markAsSent() побочный поток вполне работает с Persistence.

В CUBA приложении как и в обычном Spring приложении, бины - это синглтоны, и они используются одновременно многими разными потоками исполнения в параллели. Никаких “копий объекта” не создается.

Не видя ваш код, трудно определить причину проблемы. Единственная догадка - это может быть вы запускаете побочные потоки прямо в конструкторе бина, когда зависимости бина еще не проинжектированы.