Springd NamedParameterJDBCTemplate присоединиться к сеансу Hibernate? - PullRequest
0 голосов
/ 19 апреля 2011

Длинная история ниже. Короткий вопрос: Как я могу получить NamedParameterJDBCTemplate Spring присоединиться к сеансу Hibernate? У нас есть приложение, использующее Spring и Hibernate, весь наш слой данных - с Hibernate. Но теперь есть случай использования, когда у нас есть родительский объект, для которого вся логика гибернации существует. Родительский объект имеет много (> 4000) деталей, которые мы хотим вставить, используя jdbctemplate Spring, все в одной транзакции (вместо использования hibernate). Родительский объект сохраняется, идентификатор Родителя (который является последовательностью оракула) устанавливается и доступен для чтения через объект. Мы только должны совершить, чтобы постоянно хранить его. Граница транзакции устанавливается для метода, который также запускает 4000+ jdbctemplate вставок деталей. Детали, будучи деталями, нуждаются в ссылке на родительский объект, который является идентификатором родителя, доступным во время выполнения 4000+ вставок. Однако на вставке первой детали я получаю

integrity constraint (FK_008) violated - parent key not found

Я думаю, что понимаю, поскольку jdbctemplate, вероятно, использует другой сеанс и, следовательно, другую транзакцию. Я попытался установить propegation: обязательный атрибут транзакции в методе, выполняющем 4000+ вставок, ожидая, что объединения транзакции будет достаточно, чтобы иметь возможность прочитать новый незафиксированный родительский идентификатор, но этого было явно недостаточно. Я надеюсь, что смогу каким-то образом подключить сеанс гибернации к весеннему jdbctemplate, но пока я не смог этого сделать. SpringJDBC принимает источник данных в качестве аргумента, менеджер jtatransaction принимает Hibernate SessionFactory, и до сих пор я чувствую, что восток - это восток и запад, и никогда не встречаться между ними. Есть ли другие способы сделать так, чтобы Spring jdbctemplate участвовал в сессии Hibernate? (кроме пробной фиксации вставки родителя, чтобы идентификатор родителя был доступен для jdbctemplate).

HibernateSessionFactory - это org.springframework.orm.hibernate3.LocalSessionFactoryBean с источником данных в качестве одного из аргументов.

TransactionManager - это org.springframework.orm.hibernate3.HibernateTransactionManager, который получает sessionFactory в качестве аргумента.

NamedParameterJDBCTemplate создается в установщике sqlInserter:

public void setDataSource(DataSource dataSource) {
    jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}

Надеюсь, кто-нибудь поможет мне здесь.

Ура, Йерун

Ответы [ 2 ]

2 голосов
/ 19 апреля 2011

Вы должны сделать свои 4000+ вставок через Hibernate с помощью техники пакетных обновлений. :

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

ScrollableResults customers = session.getNamedQuery("GetCustomers")
    .setCacheMode(CacheMode.IGNORE)
    .scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( customers.next() ) {
    Customer customer = (Customer) customers.get(0);
    customer.updateStuff(...);
    if ( ++count % 20 == 0 ) {
        //flush a batch of updates and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();
0 голосов
/ 19 апреля 2011

Проблема в том, что после вставки родительского объекта мне нужно было сделать Session.flush.Это вынуждает выполнять оператор вставки (в транзакции), а постоянный родительский объект будет доступен в сеансе. Для меня это теперь работает как чудо.

...