【发布时间】:2021-11-02 13:33:14
【问题描述】:
我有 Spring 引导单元测试(使用 @SpringBootTest 注释的类)在使用我的 IDE 时运行得很好。当我使用 Maven (mvn test) 运行它们时,它们都因相同的原因而失败:
原因:org.springframework.beans.factory.BeanCreationException:在类路径资源[my/package/config/DatasourceConfiguration.class]中定义名称为“entityManagerFactory”的bean创建错误:调用init方法失败;嵌套异常是 org.hibernate.AnnotationException:无法实例化 AttributeConverter [my.package.enum.AbstractEnumConverter] 引起:org.hibernate.AnnotationException:无法实例化 AttributeConverter [my.package.enum.AbstractEnumConverter] 引起:java.lang.NoSuchMethodException: my.package.AbstractEnumConverter.
()
我使用通用 AbstractEnumConverter 来转换我的实体上的枚举。 它看起来像这样:
@Converter
public abstract class AbstractEnumConverter<T extends Enum<T> & EnumInterface<E>, E> implements AttributeConverter<T, E> {
private static Logger logger = LoggerFactory.getLogger(AbstractEnumConverter.class);
private final Class<T> clazz;
public AbstractEnumConverter(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public E convertToDatabaseColumn(T attribute) {
return attribute != null ? attribute.getKey() : null;
}
@Override
public T convertToEntityAttribute(E dbData) {
if (dbData == null)
return null;
T[] enums = clazz.getEnumConstants();
for (T e : enums) {
if (e.getKey().equals(dbData))
return e;
}
logger.info("Could not find value {} for class {}",dbData,clazz.getName());
return null;
}
}
这是我使用的枚举示例:
public enum ExampleEnum implements EnumInterface<Integer> {
KEY(1);
private final Integer key;
ExampleEnum(Integer key) {
this.key = key;
}
@Override
public Integer getKey() {
return key;
}
public static class Converter extends AbstractEnumConverter<ExampleEnum, Integer> {
public Converter() {
super(ExampleEnum.class);
}
}
}
似乎 maven 出于某些我不知道的原因试图实例化我的 AbstractEnumConverter 类。 IDE 单元测试和运行应用程序时一切正常。
【问题讨论】:
-
你不应该首先将该注释应用于抽象类。
-
你说的是@Converter注解吗?如果是这样,你能给我一个解释吗?我已经阅读了多篇文章,建议以这种方式来避免每个枚举创建一个转换器。
-
是的,但是您仍然需要为每种类型创建具体的子类,以便您的
@Converter具有无参数构造函数。 -
我有一个具体的内部类,在每个枚举中扩展 AbstractEnumConverter(参见上面代码中的类 Converter)。我的抽象类没有任何无参数构造函数,因为我需要在构建对象时传递该类。
-
对,所以
@Converter应该在这些类上,而不是抽象基类上。 (可以说,Hibernate 应该知道无论如何都要跳过基类,并且您可能会考虑提交错误,但这似乎是问题所在。)
标签: java spring-boot hibernate maven unit-testing