Это немного странно, но когда аннотация @LastModifiedDate используется для моей сущности, она запускает дополнительное обновление при сохранении нового объекта.
Если я установлю @EnableJpaAuditing (modifyOnCreate = false), то это будет только вставка, но дата последнего изменения не будет установлена при сохранении новой сущности.
Есть ли способ установить дату последнего изменения при вставке без дополнительного обновления базы данных или я что-то упустил?
Вот мой код:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaConfig {
@Bean
public AuditorAware<String> auditorProvider() {
return () -> System.getProperty("user.name", "undefined");
}
}
Абстрактная сущность с геттерами (работающая с геттерами, поскольку я использую их в других местах для Hibernate):
@MappedSuperclass
public abstract class AbstractGenericJson extends GenericJson {
private DateTime createdDate;
private DateTime lastModifiedDate;
private String createdBy;
private String lastModifiedBy;
@Column(name = "audit_create_ts", nullable = false, updatable = false)
@CreatedDate
@Convert(converter = JodaDateTimeConverter.class)
public DateTime getCreatedDate() {
return createdDate;
}
public void setCreatedDate(DateTime createdDate) {
this.createdDate = createdDate;
}
@Column(name = "audit_update_ts")
@LastModifiedDate
@Convert(converter = JodaDateTimeConverter.class)
public DateTime getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(DateTime lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
@Column(name = "audit_user_tx", updatable = false)
@CreatedBy
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
@Column(name = "audit_upd_user_tx")
@LastModifiedBy
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
...
Класс сущности
@Entity
@EntityListeners(AuditingEntityListener.class)
public class ConsumerInteraction extends AbstractGenericJson {
private UUID uuid;
@Id
@GeneratedValue
@Column(name = "uuid")
public UUID getId() {
return uuid;
}
...
Repo:
@Repository
public interface InteractionRepo extends JpaRepository<ConsumerInteraction, UUID>{}
Мой тест:
@SpringBootTest(
properties = {
"spring.jpa.properties.hibernate.jdbc.time_zone=UTC",
"logging.level.org.springframework.data.auditing=DEBUG"
})
@RunWith(SpringRunner.class)
@DataJpaTest
@Import(JpaConfig.class)
public class InteractionRepoTest {
@Autowired
InteractionRepo dao;
@Test
public void testInsertSingle() {
ConsumerInteraction i = new ConsumerInteraction();
i.setCustomId(290050);
i = dao.save(i);
dao.flush();
...
И журнал, который показывает два события Touched, одно для null uuid, а затем еще одно после генерирования uuid, что, как я понимаю, является причиной последующего обновления, поскольку никакие другие поля не были изменены.
2018/05/06 00:36:01 DEBUG | main | o.s.d.a.AuditingHandler:161 - Touched ConsumerInteraction{uuid=null, id=290050} - Last modification at java.util.GregorianCalendar[time=1525563361086,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2018,MONTH=4,WEEK_OF_YEAR=18,WEEK_OF_MONTH=1,DAY_OF_MONTH=6,DAY_OF_YEAR=126,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=36,SECOND=1,MILLISECOND=86,ZONE_OFFSET=0,DST_OFFSET=3600000] by xxx
2018/05/06 00:36:05 DEBUG | main | o.s.d.a.AuditingHandler:161 - Touched ConsumerInteraction{uuid=4e38645b-aa13-435d-8416-4bb3792a2482, id=290050} - Last modification at java.util.GregorianCalendar[time=1525563365716,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2018,MONTH=4,WEEK_OF_YEAR=18,WEEK_OF_MONTH=1,DAY_OF_MONTH=6,DAY_OF_YEAR=126,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=36,SECOND=5,MILLISECOND=716,ZONE_OFFSET=0,DST_OFFSET=3600000] by xxx
Hibernate: insert into tInteraction (audit_user_tx, audit_create_ts, audit_upd_user_tx, audit_update_ts, average_value, company_names, consumer, contract_id, id, description, desk, duration, ext_party_id, include_in_vote, interaction_date, interaction_id, interaction_type, interaction_value, override_value, party_name, payer_allocation_name, regions, sectors, sell_side_contacts, status, updated_by, updated_date, user_comment, user_rating, period_id, region, uuid) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update tInteraction set audit_upd_user_tx=?, audit_update_ts=?, average_value=?, company_names=?, consumer=?, contract_id=?, description=?, desk=?, duration=?, ext_party_id=?, include_in_vote=?, interaction_date=?, interaction_id=?, interaction_type=?, interaction_value=?, override_value=?, party_name=?, payer_allocation_name=?, regions=?, sectors=?, sell_side_contacts=?, status=?, updated_by=?, updated_date=?, user_comment=?, user_rating=? where uuid=?
Использование Spring Boot jpa 1.5.12 и Hibernate 5.2.16.Final.
Извините за длинный пост, но я собираюсь отказаться от использования @LastModifiedDate. Спасибо!