As is described in this post: https://stackoverflow.com/questions/36700139/hibernate-valuegenerationtype-applied-at-insert-but-not-update-time the generated values by database in timing “ALWAYS” is not working as expected
The method referenceColumnInSql is defined to return true and the method getDatabaseGeneratedReferencedColumnValue returns the value “current_timestamp”
So it is expected that the update statement also include the column and sets it’s value to “current_timestamp” but the column is missing in the update statemet and it is only included in the select statement to get the value from the database, but the value is never changed.
It is necesary to include the column in the update statement.
This is the annotation definition: {code:java} package com.halftau.db.annotations;
import com.halftau.db.behaviour.ModificationTimeGeneratorImpl; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import org.hibernate.annotations.ValueGenerationType;
@ValueGenerationType(generatedBy = ModificationTimeGeneratorImpl.class) @Retention(RetentionPolicy.RUNTIME) public @interface ModificationTime {} {code}
This is the implementation class definition:
{code:java} package com.halftau.db.behaviour;
import com.halftau.db.annotations.ModificationTime; import org.hibernate.tuple.AnnotationValueGeneration; import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.ValueGenerator;
public class ModificationTimeGeneratorImpl implements AnnotationValueGeneration<ModificationTime> { @Override public void initialize(ModificationTime annotation, Class<?> propertyType) { System.out.println("INICIALIZANDO MODIFICATION TIME"); }
/** * Generate value on ALWAYS * @return when to generate the value */ @Override public GenerationTiming getGenerationTiming() { return GenerationTiming.ALWAYS; }
/** * Returns null because the value is generated by the database. * @return null */ @Override public ValueGenerator<?> getValueGenerator() { return null; }
/** * Returns true because the value is generated by the database. * @return true */ @Override public boolean referenceColumnInSql() { return true; }
/** * Returns the database-generated value * @return database-generated value */ @Override public String getDatabaseGeneratedReferencedColumnValue() { return "LOCALTIMESTAMP"; } } {code}
when I insert the entity in the database, I got these statements:
{noformat} Hibernate: select nextval ('project_proj_id_SEQ') Hibernate: /* insert com.halftau.tasks.entities.Project */ insert into project (acco_id, alive, description, destruction_time, external_id, modification_time, name, proj_id, tena_id) values (?, ?, ?, ?, ?, LOCALTIMESTAMP, ?, ?, ?) Hibernate: /* get generated state com.halftau.tasks.entities.Project */ select project_.creation_time as creation5_2_, project_.modification_time as modifica9_2_ from project project_ where project_.proj_id=? and project_.tena_id=? {noformat}
Which is correct. It references the column "modification_time" (Annotated with the ModificationTime annotation in the entity definition) and set que insert statement using "LOCALTIMESTAMP" as defined in the getDatabaseGeneratedReferencedColumnValue() method.
But when I update the entity I get these statements:
{noformat} Hibernate: /* update com.halftau.tasks.entities.Project */ update project set alive=?, description=?, destruction_time=?, external_id=?, name=? where proj_id=? and tena_id=? Hibernate: /* get generated state com.halftau.tasks.entities.Project */ select project_.modification_time as modifica9_2_ from project project_ where project_.proj_id=? and project_.tena_id=? {noformat}
Which is crearly clearly wrong, because it doesn't reference the column in the UPDATE statement (should set "modification_time=LOCALTIMESTAMP") but it query the value to get the "updated generated" value. But the value doesn't change, because the field is missing in the update statement.
I tried to generate a test case for this submission, but i can't make it work. But it seems to me that the information here is very clear and you can check it easily.
Thanks Pablo Perich
|
|