Open Draymonders opened 4 years ago
报错的源码如下
if (!property.isImmutable() || property.getWither() != null || ReflectionUtils.isKotlinClass(owner.getType())) { delegate.setProperty(property, value); this.bean = delegate.getBean(); return; } PreferredConstructor<?, ?> constructor = owner.getPersistenceConstructor(); if (constructor == null) { throw new IllegalStateException(String.format(NO_SETTER_OR_CONSTRUCTOR, property.getName(), owner.getType())); } if (!constructor.isConstructorParameter(property)) { throw new IllegalStateException( String.format(NO_CONSTRUCTOR_PARAMETER, property.getName(), constructor.getConstructor())); } constructor.getParameters().forEach(it -> { if (it.getName() == null) { throw new IllegalStateException( String.format("Cannot detect parameter names of copy constructor of %s!", owner.getType())); } }); EntityInstantiator instantiator = instantiators.getInstantiatorFor(owner); this.bean = (T) instantiator.createInstance(owner, new ParameterValueProvider() { /* * (non-Javadoc) * @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter) */ @Override @Nullable @SuppressWarnings("null") public Object getParameterValue(Parameter parameter) { return property.getName().equals(parameter.getName()) // ? value : delegate.getProperty(owner.getRequiredPersistentProperty(parameter.getName())); } });
阅读代码, mongoRepository 在 setPorperty 的时候 会先判断 当前字段是否是不可变的,是否被@wither修饰,以及是否是kotlin的源码,如果字段不是final修饰的,或者变量有@wither修饰,则可以直接设置value。
mongoRepository
setPorperty
@wither
接下来,判断字段是否是构造函数中出现的,如果也不是,说明 字段既是final修饰,又没有构造函数可以初始化, 就会报错。
setProperty 抛出异常 IllegalStateException
报错的源码如下
阅读代码,
mongoRepository
在setPorperty
的时候 会先判断 当前字段是否是不可变的,是否被@wither修饰,以及是否是kotlin的源码,如果字段不是final修饰的,或者变量有@wither
修饰,则可以直接设置value。接下来,判断字段是否是构造函数中出现的,如果也不是,说明 字段既是final修饰,又没有构造函数可以初始化, 就会报错。
最后解决方案: