Reputation: 1608
I need to check if my actual entity is different from the old one.
I use reflection because my method must be standardized.
For each column, I update the value if and only if it's not null (because i read it from a CSV and a column may be not specified).
for(Field column : fields){
column.setAccessible(true);
Object newValue = column.get(myObject);
if( newValue != null && !newValue.equals(column.get(oldObject))){
column.set(oldObject, newValue);
}
}
this.entitymanager.merge(oldObject)
If I do the changes like that, no UPDATE query is done.
If I change the value in the normal way oldobject.setValue(newValue)
the query is done and the record is updated.
Why no UPDATE query is done by the entity manager if I change value via reflection?
Upvotes: 1
Views: 530
Reputation: 1608
Thank to @Ken Chan answer, I correct the method using getters and setters.
for(Field column : columns){
Method mSet = myclass.getMethod("set"+ StringUtils.capitalize(column.getName()), column.getType());
Method mGet = myclass.getMethod("get"+ StringUtils.capitalize(column.getName()));
Object newValue = mGet.invoke(articolo);
if( newValue != null && !newValue.equals(mGet.invoke(old))){
mSet.invoke(old, newValue);
}
}
I must pay attention to methods' name. If entity have the property description
, there must be also getDescription()
and setDescription()
.
Now it works
Upvotes: 0
Reputation: 90427
Just find some good information about such behaviour at this :
By default when using weaving/agent EclipseLink uses attribute change tracking to detect changes. This will not detect changes made through reflective field access (method access is ok though).
You can change the default using the @ChangeTracking annotation to deferred which will detect change made through reflection. i.e. @ChangeTracking(ChangeTrackingType.DEFERRED)
You could also disable weaving, or weaving of change tracking in the persistence.xml using, "eclipselink.weaving.changetracking"="false"
So there are couple of solutions that can try :
Upvotes: 2