Поле базы данных по умолчанию не извлекается при использовании @Transactional - PullRequest
0 голосов
/ 07 марта 2019

У меня есть следующая простая сущность FileRegistry:

@Getter
@Setter
@Entity
@ToString
@Table(name = "file_store")
public class FileRegistry {

   @Id
   private String name;

  /**
   * Creation timestamp of the registry
   * This value is automatically set by database, so setter method
   * has been disabled
   */
   @Setter(AccessLevel.NONE)
   @Column(insertable = false, updatable = false)
   private LocalDateTime creationDate;
}

Следующий файловый репозиторий DAO:

@Repository
public interface FileRepository extends JpaRepository<FileRegistry, String> { }

и следующий тест Spring Boot:

@SpringBootTest(classes=PersistTestConfig.class, properties = { "spring.config.name=application,db"})
@ActiveProfiles("test")
@Transactional
public class FileRepositoryTest {

@Autowired
FileRepository fileRepository;

@Test
void insertFileTest() {
    assertNotNull(fileRepository, "Error initializing File repository");

    // Check registry before insertion
    List<FileRegistry> allFiles = fileRepository.findAll();
    assertNotNull(allFiles, "Error retrieving files from registry");
    assertThat(allFiles.size(), is(0));

    // Insert file
    FileRegistry fileRegistry = new FileRegistry();
    fileRegistry.setName("Test");

    fileRepository.save(fileRegistry);

    // Check that the insertion was successful
    allFiles = fileRepository.findAll();
    assertNotNull(allFiles, "Error retrieving files from registry");
    assertThat(allFiles.size(), is(1));
    assertEquals("File registry name mismatch", "Test", allFiles.get(0).getName());

    System.out.println(allFiles.get(0));
  }
} 

Класс конфигурации постоянства определен следующим образом:

@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
@EnableJpaRepositories    
public class PersistTestConfig {
}

Таблица file_store определена в H2 как:

    CREATE TABLE file_store (name VARCHAR NOT NULL, creation_date TIMESTAMP(3) DEFAULT NOW() NOT NULL, CONSTRAINT file_store_pk PRIMARY KEY (name));

Все работает нормально, за исключением того, что когда я использую @Transactional на уровне тестирования (в основном длявыгоды от откатов, т. е. очистки базы данных в каждом тесте) для поля creationDate выбирается нулевое значение:

FileRegistry(name=Test, creationDate=null)

Когда я удаляю @Transactional из класса теста, извлеченное значение содержитдата, вычисленная по H2:

FileRegistry(name=Test, creationDate=2019-03-07T17:08:13.392)

Я попытался очистить и объединить экземпляр вручную, но безрезультатно.Если честно, сейчас я немного растерялся из-за того, как на самом деле работает @Transactional, фактически читая документы и просматривая код, базовая реализация JpaRepository (SimpleJpaRepository) аннотируется как @Transactional(readOnly = true).

Небольшая помощь по этому вопросу была бы очень признательна.

1 Ответ

0 голосов
/ 07 марта 2019

Хорошо, разобрался.

Простое обновление entityManager.refresh(allFiles.get(0)); решает проблему.

Я также тестировал, используя @Generated(INSERT) специфическую аннотацию в Hibernate * вполе entity creationDate, и оно также работало нормально.

Кстати, в конце концов я решил отказаться от этого в пользу использования JpaAuditing функций Spring Data и аннотирования поля аннотацией @CreatedDate для заполнения значения.вместо того, чтобы полагаться на дату БД (кстати, с точки зрения производства, вы, вероятно, не должны полагаться на время БД).Для меня это больше, скажем так, «правильный» и упругий способ делать вещи.

...