Spring boot 在@DataJpaTest中启用@Converter
我正试图通过JPA保存LocalDate。遵循本指南:我实现了一个转换器 现在这个工作很好 然而,我有一些用@DataJpaTest注释的RepositoryTests,它们应该使用这个转换器 那些现在坏了。我得到了一些东西Spring boot 在@DataJpaTest中启用@Converter,spring-boot,jpa,spring-data-jpa,integration-testing,Spring Boot,Jpa,Spring Data Jpa,Integration Testing,我正试图通过JPA保存LocalDate。遵循本指南:我实现了一个转换器 现在这个工作很好 然而,我有一些用@DataJpaTest注释的RepositoryTests,它们应该使用这个转换器 那些现在坏了。我得到了一些东西 wrong column type encountered in column [...] in table [...]; found [date (Types#DATE)], but expecting [timestamp (Types#TIMESTAMP)] 这正是
wrong column type encountered in column [...] in table [...]; found [date (Types#DATE)], but expecting [timestamp (Types#TIMESTAMP)]
这正是我添加该死的转换器的原因。因此,显然转换器没有在@DataJpaTest的上下文中使用。
我怎样才能改变这一点
所讨论的可嵌入类:
@数据
@NoArgsConstructor(access=AccessLevel.PROTECTED)
@AllArgsConstructor
@建筑商
@可嵌入
公共类MyEntity{
@纵队
私有localdatetostore;
}
转换器:
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return locDate == null ? null : Date.valueOf(locDate);
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return sqlDate == null ? null : sqlDate.toLocalDate();
}
}
提前谢谢 问题在于@DataJpaTest没有扫描@Converter类,这在 @WebMvcTest的相关部分(工作正常): 要测试SpringMVC控制器是否按预期工作,请使用 @WebMvcTest注释@WebMvcTest自动配置Spring MVC 基础架构并将扫描的bean限制为@Controller, @ControllerAdvice、@JsonComponent、转换器、通用转换器、, 筛选器、WebMVCConfiguer和HandlerMethodArgumentResolver 其中@DataJpaTest: 您可以使用@DataJpaTest注释来测试JPA应用程序。通过 默认情况下,它扫描@Entity类并配置Spring数据JPA 存储库 这可能是Spring中的一个Bug,因为在我看来,加载转换器应该始终与JPA测试相关(类似于此) 我的解决方案是在测试中手动加载转换器,方法是在测试中添加一个新的排除过滤器:
@DataJpaTest
@OverrideAutoConfiguration(enabled = true)
@TypeExcludeFilters(DataJpaTypeExcludeFilterWithConverter.class)
class SomeTest {
...
}
自定义筛选器:
public class DataJpaTypeExcludeFilterWithConverter extends StandardAnnotationCustomizableTypeExcludeFilter<DataJpaTest> {
private static final Set<Class<?>> DEFAULT_INCLUDES;
static {
Set<Class<?>> includes = new LinkedHashSet<>();
includes.add(Converter.class);
includes.add(GenericConverter.class);
try {
includes.add(Module.class);
}
catch (Throwable ex) {
// ignore
}
DEFAULT_INCLUDES = unmodifiableSet(includes);
}
protected DataJpaTypeExcludeFilterWithConverter(Class<?> testClass) {
super(testClass);
}
@Override
protected Set<Class<?>> getDefaultIncludes() {
return DEFAULT_INCLUDES;
}
}
公共类DataJpaTypeExcludeFilterWithConverter扩展了StandardAnnotationCustomableTypeExcludeFilter{
私有静态最终集>包含=新LinkedHashSet();
包括.add(Converter.class);
includes.add(GenericConverter.class);
试一试{
包括.add(Module.class);
}
捕获(可丢弃的ex){
//忽略
}
默认包含=不可修改集(包含);
}
受保护的数据JPATypeExcludeFilterWithConverter(类testClass){
超级(测试类);
}
@凌驾
受保护集请向我们展示有问题的代码以及有问题的实体作为旁注,您使用的是哪个Hibernate版本?最新的Hibernate版本对java.time
类型提供了相当不错的支持,消除了对回复的自定义转换器hanks的需要。我更新了问题。你有没有试过我的解决方案?
@DataJpaTest
@OverrideAutoConfiguration(enabled = true)
@TypeExcludeFilters(DataJpaTypeExcludeFilterWithConverter.class)
class SomeTest {
...
}
public class DataJpaTypeExcludeFilterWithConverter extends StandardAnnotationCustomizableTypeExcludeFilter<DataJpaTest> {
private static final Set<Class<?>> DEFAULT_INCLUDES;
static {
Set<Class<?>> includes = new LinkedHashSet<>();
includes.add(Converter.class);
includes.add(GenericConverter.class);
try {
includes.add(Module.class);
}
catch (Throwable ex) {
// ignore
}
DEFAULT_INCLUDES = unmodifiableSet(includes);
}
protected DataJpaTypeExcludeFilterWithConverter(Class<?> testClass) {
super(testClass);
}
@Override
protected Set<Class<?>> getDefaultIncludes() {
return DEFAULT_INCLUDES;
}
}