JPA/Hibernate bulk(batch) insert

后端 未结 3 1684
我寻月下人不归
我寻月下人不归 2020-12-03 01:32

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 ha

相关标签:
3条回答
  • 2020-12-03 01:45

    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 each INSERT.

    Session.doWork is very handy for facilitating this.

    private MyParentObject saveMyParentObject(final MyParentObject parent, final List<MyChildObject> children)
    {
        transaction = session.beginTransaction();
        try
        {
            session.save(parent); // NOTE: parent.parentId assigned and returned here
    
            session.doWork(new Work()
            {
                public void execute(Connection con) throws SQLException
                {
                    // hand written insert SQL - can't use hibernate
                    PreparedStatement st = con.prepareStatement("INSERT INTO my_child (parent_id, name, ...) values (?, ?, ...)");
    
                    for (MyChildObject child : children)
                    {
                        MyChildObject child = new MyChildObject();
                        child.setParentId(parent.getParentId()); // assign parent id for foreign key
    
                        // hibernate can't help, determine jdbc parameters manually
                        st.setLong(1, child.getParentId());
                        st.setString(2, child.getName());
                        ...
                        st.addBatch();
                    }
    
                    // NOTE: you may want to limit the size of the batch
                    st.executeBatch();
                }
            });
    
            // if your parent has a OneToMany relationship with child(s), refresh will populate this 
            session.refresh(parent);
            transaction.commit();
            return parent;
        }
        catch(Throwable e)
        {
            transaction.rollback();
            throw new RuntimeException(e);
        }   
    }
    
    0 讨论(0)
  • 2020-12-03 02:03

    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

    0 讨论(0)
  • 2020-12-03 02:06

    If you're using the database to generate ids, then Hibernate has to execute a query to generate the primary key for each entity.

    0 讨论(0)
提交回复
热议问题