@LastModifiedDate вызывает дополнительное обновление в базе данных - PullRequest
0 голосов
/ 06 мая 2018

Это немного странно, но когда аннотация @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. Спасибо!

1 Ответ

0 голосов
/ 07 мая 2018

Найдена проблема с TimeZone по умолчанию. По-видимому, lastmodifieddate, похоже, устанавливается в местном часовом поясе, тогда как я использую UTC для Hibernate. Во время отладки я заметил, что lastModifiedDate всегда делает мою сущность грязной, потому что часовые пояса отметки времени не совпадают.

Обновлен базовый класс для использования java.util.Date для меток времени и удален конвертер из Joda DateTime. Похоже, проблема решена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...