Я попытался настроить несколько источников данных, включая 2 источника данных.
datasource1
, который помечен @Primary
.datasource2
.затем запросите данные, используя findAll()
(которые принадлежат @Primary datasource, datasource1), они работают без каких-либо ошибок.
но получил следующую ошибку, когда я вызвал метод findAll()
, принадлежащий datasource2
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.example.linewebhookjava.entity.datasource2.Projects2.itemUpdates: could not initialize proxy - no Session]
Я попробовал изменить @ElementCollection(fetch = FetchType.LAZY)
на @ElementCollection(fetch = FetchType.EAGER)
в Projects2
сущности.
или
помести это spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
в application.properties
ошибка исчезла. Но дело в том, почему происходит сбой в источнике данных2 (вторичном источнике данных).
Вывод: вызов findAll()
, принадлежащий datasource
с @Primary
, работает нормально, но не работает на findAll()
вторичного источника данных.
Кроме того, я попробовал заменить аннотацию @Primary
на другую datasource
.
(Вот мой код с sql и docker-compose.yml https://github.com/annopud/line-webhook-java/tree/no_session)
Извините, я забыл, что это частный репозиторий. Я уже изменил его на общедоступный.
По умолчанию Spring устанавливает следующее:
spring.jpa.open-in-view=true
Это заставляет Spring открывать транзакцию каждый раз, когда осуществляется вызов контроллера; если у вас есть несколько менеджеров транзакций, это происходит на основном.
Опубликованная вами ошибка связана с сериализацией json из объекта (с коллекцией, которая в случае отложенной загрузки является просто прокси), поэтому она работает, когда транзакция открывается, поскольку уровень «представления» (в данном случае , на первичном), но не на другом: каждый вызов TestSecondController
имеет открытую транзакцию, но это делается в первичном менеджере транзакций, так что это бесполезно для сериализации Project2
сущностей. Размещение аннотаций @Transactional
на контроллерах не решит проблему, поскольку сериализация происходит после возврата метода и, следовательно, после закрытия транзакции.
Попробуйте установить spring.jpa.open-in-view=false
в файле свойств; в этом случае, если все коллекции читаются как ленивые, вы должны получить на обоих контроллерах одну и ту же ошибку.
Возможно, возникает вопрос: почему вы должны заставить это приложение Spring Boot управлять обоими источниками данных? Поскольку Spring не поддерживает готовые распределенные транзакции (вы можете положиться на такие решения, как Atomikos), возможно, лучше разделить приложение по вертикали, заставив контроллеры использовать значение открытия по умолчанию и отображать объекты с отложенной загрузкой. , в более понятном виде.
Спасибо, @FrancescoPoli. Да, я получил одну и ту же ошибку на обоих контроллерах, когда попробовал установить spring.jpa.open-in-view=false
. Я просто хотел провести эксперимент, пока изучаю, как настроить несколько источников данных в приложении весенней загрузки. Вы не возражаете, если я спрошу, какие темы или ключевые слова мне нужно выучить, чтобы полностью понять ваш ответ?
Привет, репозиторий кода на GH недоступен. Можете ли вы проверить URL в сообщении?