JPA/Hibernate 批量(批量)插入
这是我在阅读了有关 jpa 批量插入的几个主题后创建的简单示例,我有 2 个持久对象 User 和 Site。一个用户可以拥有多个站点,因此我们这里有一对多的关系。假设我想创建用户并创建/链接多个站点到用户帐户。考虑到我愿意对 Site 对象使用批量插入,代码如下所示。
User user = new User("John Doe");
user.getSites().add(new Site("google.com", user));
user.getSites().add(new Site("yahoo.com", user));
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(user);
tx.commit();
但是当我运行此代码(我使用 hibernate 作为 jpa 实现提供程序)时,我看到以下 sql 输出:
Hibernate: insert into User (id, name) values (null, ?)
Hibernate: call identity()
Hibernate: insert into Site (id, url, user_id) values (null, ?, ?)
Hibernate: call identity()
Hibernate: insert into Site (id, url, user_id) values (null, ?, ?)
Hibernate: call identity()
那么,我的意思是“真正的”批量插入不起作用,或者我很困惑?
这是此示例项目的源代码,这是 Maven 项目,因此您只需下载并运行 mvn install 来检查输出。
更新:
在 Ken Liu 善意建议后,我已禁用站点对象 id 自动生成:
User user = new User("John Doe");
user.getSites().add(new Site(1, "google.com", user));
user.getSites().add(new Site(2, "yahoo.com", user));
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(user);
tx.commit();
现在我在调试输出中有以下行:
DEBUG: org.hibernate.jdbc.AbstractBatcher - Executing batch size: 2
它有效!
Here is simple example I've created after reading several topics about jpa bulk inserts, I have 2 persistent objects User, and Site. One user could have many site, so we have one to many relations here. Suppose I want to create user and create/link several sites to user account. Here is how code looks like, considering my willing to use bulk insert for Site objects.
User user = new User("John Doe");
user.getSites().add(new Site("google.com", user));
user.getSites().add(new Site("yahoo.com", user));
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(user);
tx.commit();
But when I run this code (I'm using hibernate as jpa implementation provider) I see following sql output:
Hibernate: insert into User (id, name) values (null, ?)
Hibernate: call identity()
Hibernate: insert into Site (id, url, user_id) values (null, ?, ?)
Hibernate: call identity()
Hibernate: insert into Site (id, url, user_id) values (null, ?, ?)
Hibernate: call identity()
So, I means "real" bulk insert not works or I am confused?
Here is source code for this example project, this is maven project so you have only download and run mvn install to check output.
UPDATED:
After Ken Liu kindly advise, I've disabled Site object id auto generation:
User user = new User("John Doe");
user.getSites().add(new Site(1, "google.com", user));
user.getSites().add(new Site(2, "yahoo.com", user));
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(user);
tx.commit();
Now I have following line in debug output:
DEBUG: org.hibernate.jdbc.AbstractBatcher - Executing batch size: 2
It works!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您使用数据库生成 ids,则 Hibernate 必须执行查询来为每个实体生成主键。
If you're using the database to generate ids, then Hibernate has to execute a query to generate the primary key for each entity.
我发现绕过休眠进行批量插入会更有效。您必须取消 ORM(对象关系映射),但您仍然可以利用与当前会话和事务管理关联的连接。
虽然您暂时失去了 ORM 的便利性,但回报是巨大的,特别是如果您有本机生成的 Id,因为 hibernate 通常会为每个
INSERT
执行一次SELECT
。Session.doWork
对于促进这一点非常方便。I have found it much more efficient to bypass hibernate for bulk inserts. You must do away with ORM (object relational mapping) but you can still leverage the connection associated with the current session and the transaction management.
While you temporarily lose the convenience of your ORM, the payoff is significant, especially if you have natively generated Ids since hibernate would normally perform one
SELECT
for eachINSERT
.Session.doWork
is very handy for facilitating this.我写了一篇简短的博客,其中讨论了批量插入问题,并且还提供了一个小项目的指针,该项目具有开始使用 Hibernate 进行批量插入的所有正确配置。请参阅 http://sensiblerationalization.blogspot 的详细信息.com/2011/03/quick-tip-on-hibernate-batch-operation.html
I have written a short blog which talks about batch insert gotchas and also has pointer to small project that has all the right configurations to get started with batch insert with Hibernate. See the details at http://sensiblerationalization.blogspot.com/2011/03/quick-tip-on-hibernate-batch-operation.html