Make hibernate save () and update () as optimization with one insert

I am wondering how to reduce SQL updates using the settings of Hibernate (4) and Oracle.

A simple case might be the following:

Open a session / transaction, create a new Xyz object with session.save (), process some business logic, make some changes to Xyz and call session.update () and let the session be closed as usual and Hibernate with commit to DB .

When the transaction is completed, Hibernate will perform an insert followed by an update - but in this example, all she really needs to do is the only insert, but with the latest Xyz properties.

Does anyone have any ideas / templates for this kind of thing? Or is there a way to change the behavior of Hibernate? Or is your opinion on this a complete anti-pattern?

I know that Hibernate is smart enough to omit multiple updates when one update simply overwrites another - so why doesn't it look like an insert?

This small snippet can reproduce the “question”:

MyEntity e = new MyEntity("xxx"); Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(e); e.setName("yyy"); session.getTransaction().commit(); session.close(); 

By the way, I have no triggers to worry about.

This example is very simple, and the performance problem may seem trivial, but in fact I am dealing with a more complex object (i.e. several inserts and updates) and large volumes, so avoiding the updates would be great.

+4
source share
1 answer

Is there a way to add an object to the session and it will be marked as permanent, but will not call save () (i.e., INSERT will not be created) to the very end?

Consider re-factoring to use Session.persist(Object) instead of Session.save(Object) if you want to defer execution of INSERT until the session is cleared and / or the transaction is closed.

From section 10.2 of the JBoss Hibernate Community Documentation :

You can also use persist () instead of save (), with the semantics defined in an early draft of EJB3.

  • persist() makes the temporary instance persistent. However, this does not guarantee that the identifier value will be assigned to the permanent instance immediately; the assignment can occur during cleanup. persist() also ensures that it does not execute the INSERT if it is called outside the bounds of a transaction. This is useful for long conversations with an extended Session / persistence context.
  • save() guarantees the return of the identifier. If you need to perform an INSERT to get an identifier (for example, an "identifier" rather than a "sequence"), this INSERT occurs immediately, regardless of whether you are inside or outside the transaction. This is a problem in a long conversation with an extended Session / persistence context.

Another useful link can be found in the upper left cell of the “script-method” grid at the top of the “Put All Together” section of this blog article that describes persist() behavior for objects that were never saved as follows:

  • Object added to persistence context as new object
  • A new object inserted into the database in flush() / commit()
+1
source

Source: https://habr.com/ru/post/1484641/


All Articles