Long story below short question: How can I get Spring's NamedParameterJDBCTemplate join Hibernate's session? We've an application using Spring and Hibernate, our whole datalayer is with Hibernate. But now there is a use case where we have a parent object for which the whole hibernate logic is in place. The parent object has many (> 4000) details, which we do want to insert using Spring's jdbctemplate, all in one transaction (instead of using hibernate). The parent object is saved, the Parent's id (which is an oracle sequence) is set, and readable via the object. We only have to commit in order to permanently store it. The transaction boundary is set on a method which also fires the 4000+ jdbctemplate inserts of the details. The details, being details, do need a reference to the parent object which is the parent's id, available at the time the 4000+ insertions are being executed. However on the insert of the first detail, I get a
integrity constraint (FK_008) violated - parent key not found
I think I do understand that, as the jdbctemplate is probably using another session and therefor another transaction. I tried setting a propegation:required transaction attribute on the method doing the 4000+ inserts, expecting that the join of the transaction would be sufficient to be able to read the new uncommitted parent id, but that was obvious not enough. I'm hoping that I can somehow wire the hibernate session into spring's jdbctemplate but so far I haven't been able to do so. The SpringJDBC takes the dataSource as argument, the jtatransaction manager takes the Hibernate SessionFactory, and so far I've the feeling that east is east and west and never the twain shall meet. Are there other ways, to make Spring's jdbctemplate participating in Hibernate's Session? (except of coursing committing the parent's insert so the parent-id is available the jdbctemplate).
HibernateSessionFactory is an org.springframework.orm.hibernate3.LocalSessionFactoryBean with the dataSource as one of the arguments.
TransactionManager is the 开发者_运维问答org.springframework.orm.hibernate3.HibernateTransactionManager which gets the sessionFactory as the argument.
The NamedParameterJDBCTemplate is created in the setter of the sqlInserter:
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
Hopefully somebody can help me out here.
Cheers, Jeroen
You should do your 4000+ insertions via Hibernate via batch updates technique. :
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();
Problem is that after the insertion of the Parent Object I needed to do a Session.flush. This forces the insert statement to be executed (within the transaction), and the persistent parent object to be available in the session, For me it works like a charm now.
精彩评论