Main Tutorials

Hibernate – dynamic-insert attribute example

What is dynamic-insert

The dynamic-insert attribute tells Hibernate whether to include null properties in the SQL INSERT statement. Let explore some examples to understand more clear about it.

Dynamic-insert example

1. dynamic-insert=false

The default value of dynamic-insert is false, which means include null properties in the Hibernate’s SQL INSERT statement.

For example, try set some null values to an object properties and save it.


        StockTransaction stockTran = new StockTransaction();
        //stockTran.setPriceOpen(new Float("1.2"));
        //stockTran.setPriceClose(new Float("1.1"));
        //stockTran.setPriceChange(new Float("10.0"));
        stockTran.setVolume(2000000L);
        stockTran.setDate(new Date());
        stockTran.setStock(stock);

        session.save(stockTran);

Turn on the Hibernate “show_sql” to true, you will see the following insert SQL statement.


Hibernate: 
    insert 
    into
        mkyong.stock_transaction
        (DATE, PRICE_CHANGE, PRICE_CLOSE, PRICE_OPEN, STOCK_ID, VOLUME) 
    values
        (?, ?, ?, ?, ?, ?)

Hibernate will generate the unnecessary columns (PRICE_CHANGE, PRICE_CLOSE, PRICE_OPEN) for the insertion.

2. dynamic-insert=true

If set the dynamic-insert to true, which means exclude null property values in the Hibernate’s SQL INSERT statement.

For example, try set some null values to an object properties and save it again.


        StockTransaction stockTran = new StockTransaction();
        //stockTran.setPriceOpen(new Float("1.2"));
        //stockTran.setPriceClose(new Float("1.1"));
        //stockTran.setPriceChange(new Float("10.0"));
        stockTran.setVolume(2000000L);
        stockTran.setDate(new Date());
        stockTran.setStock(stock);

        session.save(stockTran);

Turn on the Hibernate “show_sql” to true. You will see the different insert SQL statement.


Hibernate: 
    insert 
    into
        mkyong.stock_transaction
        (DATE, STOCK_ID, VOLUME) 
    values
        (?, ?, ?)

Hibernate will generate only the necessary columns (DATE, STOCK_ID, VOLUME) for the insertion.

Performance issue

In certain situations, such as a very large table with hundreds of columns (legacy design), or a table contains extremely large data volume, insert something not necessary definitely will drop down your system performance.

How to configure it

You can configure the dynamic-insert properties value through annotation or XML mapping file.

1. Annotation


@Entity
@Table(name = "stock_transaction", catalog = "mkyong")
@org.hibernate.annotations.Entity(
		dynamicInsert = true
)
public class StockTransaction implements java.io.Serializable {

2. XML mapping


<class ... table="stock_transaction" catalog="mkyong" dynamic-insert="true">
        <id name="tranId" type="java.lang.Integer">
            <column name="TRAN_ID" />
            <generator class="identity" />
        </id>

Conclusion

This little “dynamic-insert” tweak may increase your system performance, and highly recommends to do it. However, one question in my mind is why Hibernate set it to false by default?

Follow up

1. Hibernate – dynamic-update attribute example

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
14 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
kiranyadav245
6 years ago

how it will be performance issue if dynamic-insert is false?
if dynamic-insert= false,
1. single query for n number of records
2. no null checks
if dynamic-insert= true
1. every property value checked in entity
2. every time query framed based on the values.

oscar
11 years ago

now for Hibernate 4.0+ only works @DynamicUpdate and @DynamicInsert

Ian Robertson
9 years ago

One reason that you might not want to set dynamic-insert to true is that for some databases (such as Oracle), each unique query takes up resources in the database. If you have a table with 20 columns, each of which could be present or not, that could yield as many as 1 million unique queries, which would certainly overflow any cache. By having a single prepared statement, it increases the likelihood that no new “hard parses” of the query will need to be performed by the database.

In contrast, sending null columns over the wire usually doesn’t make much of a difference in performance; often they end up fitting in the same TCP packet, and have minimal impact.

If performance is a concern, the best route is to measure the performance of both options. There are too many moving parts to be able to predict what will happen from theory alone.

Damien
10 years ago

I still have the problem.
@DynamicInsert seems not working with your settings
http://stackoverflow.com/questions/6328613/how-to-set-boolean-value-in-hibernate/17589200#17589200

Any tip ?

Arun
10 years ago

Hi
I have mapped dynamic-insert=”true” and actualElementAmount, remainingAmount are not set.
Why it is checking for checkNullability?
It should generate
insert into ChargeElement(term) values (1)

If i am missing something?

//test
ChargeElementDo chargeElementDo = new ChargeElementDo();
chargeElementDo.setTerm(1);

sess.saveOrUpdate(chargeElementDo);

Note: actualElementAmount and RemainingAmount is not null and default zero in sql server 2005

org.hibernate.PropertyValueException: not-null property references a null or transient value: my.hibernate.study.domain.ChargeElementDo.actualElementAmount
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at my.hibernate.study.test.ChargeElementTest.main(ChargeElementTest.java:28)

Ajith
11 years ago

We had the same question, too on why hibernate defaults dynamic_update and dynamic_insert to false. After close analysis, we found that the AbstractBatcher batch the SQLs based on the parameters in the insert/update. If you use dynamic insert/update false, it will batch everything for one table and there will be only that many DB hits as the number of tables that you are updating or inserting into. Else the number of batches will increase depending on how the parameters on these are. For example, if you have two different update statements in the same table, that updates two different fields on it, setting dynamic update to true will cause hibernate to sent two different update scripts in two batches, and setting it to false will cause hibernate to send both them in one batch!!!

Vikram
11 years ago

If there is performance issue, why they did not have it as default true?????????

Selman
13 years ago

Thanks for the tutorials. Great work

Stephane
13 years ago

For a MySql schema with 100 tables, each having some NOT NULL DEFAULT ” attributes, is it better to use dynamic insert true, or to make sure the persisted object contains empty strings ?

With the dynamic-insert attribute set to true, the object can be created and persisted like:

User user = new User();
user.setEmail(“[email protected]”);
user.setPassword(“apassword”);
user = userDao.makePersistent(user);

But with the dynamic-insert attribute set to false, the object must be created and persisted like:

User user = new User();
user.setEmail(“[email protected]”);
user.setPassword(“apassword”);
user.setFirstname(“”);
user.setLastname(“”);
user.setCompany(“”);
user = userDao.makePersistent(user);

In the second case, all the object properties need to be explicitly set to some non null values.

college dating rules
14 years ago

Can’t think of better ways to write this post , did a great job with this topic.

Amit
14 years ago

good article explaining the basics. I tried to read more about why the default setting for dynamic-insert & dynamic-update is false and I found that setting the property to true could degrade the performance in some cases. Here’s the extract from Hibernate in action
“Enabling either of these settings will cause Hibernate to generate some SQL at runtime, instead of using the SQL cached at startup time. The performance cost is usually small.”

This could be one of the reasons why the default setting is false.

Don Hosek
11 years ago
Reply to  mkyong

Consider this case: You have an entity with
String a;
String b;
String c;

with dynamic-insert=true, it will generate and cache a single insert statement. But if we have dynamic-insert=false, it has to generate a new SQL insert statement for each case of one of the fields null (as many as 7=2^8-1 additional cases)

Marco
14 years ago
Reply to  mkyong

Prepared statements, maybe?