1. My entity is configured for dynamic inserts and updates
2. I obtain my entity using getReference on the entityManager
3. I update a single field on this entity and then try to persist it
The update sql will be of just the updated column.Thats exactly whats happening.
Based on what I read the entity should be fetched lazily and its fields should not be loaded at all.
However I noticed that the sql is actually being executed for a select on all the fields even though the entity is fetched lazily using getReference.
Q1) Is that happening because any attempt to set any basic field will cause first all the basic fields to be loaded even if the fields specify lazy fetch?
Q2) Is the problem this that unless hibernate executes a select it will not be able to tell which fields are dirty and need an update? If so is there any way of informing hibernate about actual dirty field name?
Q3) Any suggestions on what if done will eliminate the select sql?
I tried playing with entityManager.setFlushMode(FlushModeType.COMMIT) and also setting "selectBeforeUpdate=false" but did not work.
Code:
@Entity
@org.hibernate.annotations.Entity(dynamicInsert=true, dynamicUpdate=true)
public class VerifyColControlInSql
{
@Id
@GeneratedValue
private long id;
@Basic(fetch=LAZY)
private String col1;
@Basic(fetch=LAZY)
private String col2;
String getCol1()
{
return col1;
}
void setCol1(String col1)
{
this.col1 = col1;
}
String getCol2()
{
return col2;
}
void setCol2(String col2)
{
this.col2 = col2;
}
long getId()
{
return id;
}
}
A code :
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("learnJpa");
EntityManager entityManager = emf.createEntityManager();
//insert code. Please ignore
entityManager.setFlushMode(FlushModeType.COMMIT);
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
VerifyColControlInSql v= new VerifyColControlInSql();
v.setCol1("col1");
entityManager.persist(v);
v= new VerifyColControlInSql();
v.setCol1("col1.1");
entityManager.persist(v);
tx.commit();
entityManager.close();
//long id=v.getId();//1
//new em
//code to look at. Please look at this code
entityManager = emf.createEntityManager();
entityManager.setFlushMode(FlushModeType.COMMIT);
tx = entityManager.getTransaction();
tx.begin();
v=entityManager.getReference(VerifyColControlInSql.class, 1l);
v.setCol2("col2");
tx.commit();
entityManager.close();
emf.close();
SQLS:
insert
into
VerifyColControlInSql
(col1)
values
(?)
select
verifycolc0_.id as id0_0_,
verifycolc0_.col1 as col2_0_0_,
verifycolc0_.col2 as col3_0_0_
from
VerifyColControlInSql verifycolc0_
where
verifycolc0_.id=?
update
VerifyColControlInSql
set
col2=?
where
id=?
and col2 is null
[/code]