Spring的NamedParameterJDBCTemplate加入Hibernate的会话?

发布于 2024-11-02 05:30:01 字数 1385 浏览 5 评论 0原文

下面是长话短说的问题:如何让 Spring 的 NamedParameterJDBCTemplate 加入 Hibernate 的会话? 我们有一个使用 Spring 和 Hibernate 的应用程序,我们的整个数据层都使用 Hibernate。但现在有一个用例,我们有一个父对象,整个休眠逻辑都已就位。父对象有许多(> 4000)详细信息,我们确实希望使用 Spring 的 jdbctemplate 插入这些详细信息,所有这些都在一个事务中(而不是使用 hibernate)。父对象被保存,父对象的 id(这是一个预言序列)被设置,并且可以通过对象读取。我们只需提交即可永久存储它。 事务边界是在一个方法上设置的,该方法还会触发 4000 多个 jdbctemplate 详细信息插入。 详细信息确实需要对父对象的引用,即父对象的 id,在执行 4000 多个插入时可用。然而,在插入第一个细节时,我得到了

违反完整性约束(FK_008) - 未找到父键

我想我确实理解这一点,因为 jdbctemplate 可能正在使用另一个会话,因此另一个事务。我尝试在执行 4000 多次插入的方法上设置 propegation:required 事务属性,期望事务的联接足以读取新的未提交的父 id,但这显然还不够。 我希望我能以某种方式将休眠会话连接到 spring 的 jdbctemplate 中,但到目前为止我还无法做到这一点。 SpringJDBC以dataSource为参数,jtatransaction管理器以Hibernate SessionFactory为参数,到目前为止我的感觉是东方就是东方,西方永远不会相遇。还有其他方法可以让 Spring 的 jdbctemplate 参与 Hibernate 的 Session 吗? (除了提交父级的插入以便父级 ID 可在 jdbctemplate 中使用之外)。

HibernateSessionFactory 是一个 org.springframework.orm.hibernate3.LocalSessionFactoryBean 将 dataSource 作为参数之一。

TransactionManager 是 org.springframework.orm.hibernate3.HibernateTransactionManager,它获取 sessionFactory 作为参数。

NamedParameterJDBCTemplate 是在 sqlInserter 的 setter 中创建的:

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

希望有人可以在这里帮助我。

干杯, 杰罗恩

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半衬遮猫 2024-11-09 05:30:01

您应该通过 Hibernate 通过批量更新技术进行 4000 多次插入。 :

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();

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();
青衫儰鉨ミ守葔 2024-11-09 05:30:01

问题是插入父对象后我需要执行 Session.flush。这强制执行插入语句(在事务内),并且持久父对象在会话中可用,对我来说,它现在就像一个魅力。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文