LINUX.ORG.RU

Spring Framework + EclipseLink: Одновременное использование JPA и JDBC


0

1

Доброго времени суток.

Есть приложение, в котором используется Spring + EclipseLink. Структура БД (postgresql) имеет особенность: в схеме public лежат пустые таблицы + есть куча схем в которых таблицы наследуются от public.*. Для работы с отдельными сущностями используется JPA, для работы со списками - JDBC. Для JPA и JDBC используется общий пул коннектов C3P0.

Сделал аннотацию @EmitentRequired для пометки метода как требующего переключения на конкретную схему. Есть аспект, который обрабатывает эту аннотацию. Бин аспекта, используя JPA, вызывает

entityManager.createNativeQuery("set search_path to ...").executeUpdate();
При этом нужная схема берется из данных сессии. Сам бин с аспектом имеет облать действия «request».

В бине, у которого область действия тоже «request» и который работает с JDBC, используется такой код:

@Autowired
public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource, true);
}

@Transactional(readOnly=true)
@EmitentRequired
public ListPortion getAccountList(...) {
   // Здесь идет код, который должен выполняться с уже установленной схемой
}
Но при этом получается, что соединение с БД отдается другое. Соответственно какая там в прошлый раз использовалась схема, пес его знает. То есть переключение не работает.

Проблему можно решить, обработав все переключения внутри методов, используя либо entityManager, либо jdbcTemplate в каждом конкретном случае, но хотелось бы чтобы переключение происходило автоматически.

Можно ли как-то настроить C3P0 в Spring Framework таким образом, чтобы при обработке запроса он всегда отдавал то же самое соединение?


Вопрос - а почему Вы используете JDBC при условии что уже работает JPA? JPA не позволяет получить список всех сущностей?

TheKnight ★★★
()
Ответ на: комментарий от TheKnight

мы на прошлой неделе часть кода переписали с Hibernate на plain JDBC, потому что Jasper слишком медленно работал Hibernate'ом. Обработка простого resultset'а занимает в десятки раз меньше времени.

stevejobs ★★★★☆
()
Ответ на: комментарий от TheKnight

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

vega
() автор топика

Вместо того, что бы инжектить EntityManager/Jdbctemplate, напиши обертку, которая возращяете тебе EntityManager/JdbcTemplate и в зависимости от того, какая анотация навешена (бин аспекта будет что-то писать в ThreadLocal, потом сможешь это считать) будет перед возвратом объекта делать нужные тебе действия. Т.е. просто красиво оберни тот код, который ты пишешь ручками.

dizza ★★★★★
()
Ответ на: комментарий от dizza

В принципе, хороший вариант. Только придется делать два типа аннотаций, и соответственно аспектов. Один для методов, использующих JPA, один для JDBC. И если в методе требуется использовать оба варианта, то ставить соответственно две аннотации.

Наверное так и сделаю.

vega
() автор топика
Ответ на: комментарий от stevejobs

Можно же было просто маппинг подкрутить. Все равно же потом из этого resultset'a нужные объекты руками создавать пришлось

Crocodille
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.