У меня есть довольно сложные методы, которые создают разные объекты во время его выполнения и используют их. Например, я создаю несколько изображений, а затем добавить их к статье:Hibernate: доступ к созданному объекту из разных транзакций
@Transactional
public void createArticle() {
List<Image> images = ...
for (int i = 0; i < 10; i++) {
// creating some new images, method annotated @Transactional
images.add(repository.createImage(...));
}
Article article = getArticle();
article.addImages(images);
em.merge(article);
}
Это работает правильно - изображения имеют свои идентификаторы, а затем они добавляются к статье. Проблема в том, что во время этого выполнения база данных заблокирована, и ничто не может быть изменено. Это очень неудобно, потому что изображения могут обрабатываться некоторым графическим процессором, и это может занять некоторое время.
Таким образом, мы можем попытаться удалить @Transactional
из основного метода. Это может быть хорошо. Что происходит, так это то, что изображения правильно созданы и имеют свой идентификатор. Но как только я попытаюсь добавить их к article
и вызову merge, я получаю javax.persistence.EntityNotFoundException
для изображения с ID XXXX. Диспетчер объектов не может видеть, что изображение было создано и имеет свой идентификатор. Поэтому база данных не заблокирована, но мы ничего не можем сделать.
Так что я могу сделать? Я не хочу, чтобы база данных блокировалась в течение всего выполнения, и я хочу иметь доступ к созданным объектам!
Я использую текущую версию Spring и Hibernate, все, что определено Annotations. Я не использую сессионную фабрику, я обращаюсь ко всему через javax.persistence.EntityManager
.
Объявление 1: Это может быть хорошим решением, но я забыл упомянуть, что при создании изображений мне нужно знать их идентификатор, чтобы их можно было сохранить на диск. Я полагаю, что если я не начну сохранять их своими хэшами, вызов БД будет неизбежным. Однако я все еще думаю, что это сработает, если все вызовы БД будут раздельными. –
Объявление 2: Я действительно пробовал это, но это приводит к 'javax.persistence.EntityNotFoundException', как будто две транзакции не знали друг о друге. –
попробуйте создать идентификатор изображения без блокировки с помощью @SequenceGenerator. Это создаст идентификатор, вызвав последовательность базы данных, но не будет инициировать вставку объекта непосредственно непосредственно. Http: //www.java2s.com/Tutorial/Java/0355__JPA/UseSequenceGenerator.htm. Как и у вас есть идентификатор и можете использовать его, прежде чем вставлять в себя изображение самого –