环境: Spring Boot 2.1.2.RELEASE, 弹簧数据2.1.4.RELEASE, Kotlin 1.2.x〜1.3.x, Mongodb。
我定义了一个模型类,例如:
@Document
class MeAccount : Setting() {
lateinit var id: String
val accountEntries = listOf<BankAccount>()
}
当我尝试从mongodb读取此模型时,出现异常stacktrace打击:
java.lang.UnsupportedOperationException: No accessor to set property private final java.util.List com.xxx.MeCustodianAccount.accountEntries!
at com.xxx.MeCustodianAccount_Accessor_fs514j.setProperty(Unknown Source)
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:61)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:378)
请注意,该代码与spring-boot 1.5.x和spring-data 1.x正常工作。
我该怎么做才能解决此问题? 似乎下面有许多类似的异常报告:
Spring boot 2.1.0 security change with kotlin data class?
https://github.com/arangodb/spring-data/issues/123
https://github.com/spring-projects/spring-boot/issues/15698
[已解决]在回退到Spring-boot 2.0.x和spring-data-commons 2.0.x之后工作。在将来的升级计划中将保留2.1。
答案 0 :(得分:1)
2.1中的Spring数据。改变了处理实体中最终字段的方式。它不再使用反射来覆盖字段的不变性,这通常是好的。有几种方法可以解决该问题。
这是春季队的建议:
- 添加@PersistenceConstructor来构建设置不可变字段的实体。
- 添加凋谢方法(MyEntity withXxx(…))以创建一个包含更改后的属性值的新实例。
- 或者:使用Kotlin的数据类功能。基本上,这和凋灵方法一样。
因此,您应该像这样工作:
kubectl describe pods
答案 1 :(得分:0)
仅出于记录目的,因为我没有找到有关apache cassandra的弹簧数据的相同问题,文档建议仅使用@Value以避免DTO上@Data不变变化的样板,但是在该示例之后,spring抛出UnsupportedOperationException来解决此dto必须具有龙目岛实验 @Wither 才能工作。
存储库
<T> List<T> findByActive(Class<T> class);
DTO
@Value
public class PersonDTO {
private UUID id;
private Boolean active;
}
测试-致电
List<PersonDTO> personList = personService.findByActive(PersonDTO.class);
g
java.lang.UnsupportedOperationException: No accessor to set property private final java.lang.Boolean com.x.dto.PersonDTO.active!
at com.x.dto.PersonDTO_Accessor_y82uew.setProperty(Unknown Source)
at org.springframework.data.cassandra.repository.query.DtoInstantiatingConverter.lambda$convert$0(DtoInstantiatingConverter.java:107)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:369)
at org.springframework.data.cassandra.repository.query.DtoInstantiatingConverter.convert(DtoInstantiatingConverter.java:101)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:152)
at org.springframework.data.cassandra.repository.query.CassandraQueryExecution$ResultProcessingConverter.convert(CassandraQueryExecution.java:267)
at org.springframework.data.cassandra.repository.query.CassandraQueryExecution$ResultProcessingExecution.execute(CassandraQueryExecution.java:232)
at org.springframework.data.cassandra.repository.query.AbstractCassandraQuery.execute(AbstractCassandraQuery.java:103)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy145.findByActive(Unknown Source)
at com.x.service.impl.PersonServiceImpl.findByActive(PersonServiceImpl.java:22)
at com.x.PersonRepositoryTest.findByActive(PersonRepositoryTest.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Spring Data for Apache Cassandra - Reference Documentation
避免为投影DTO设计样板代码 使用Project Lombok简化DTO的代码,该项目提供了 @Value注释(不要与Spring的@Value注释混淆 如前面的界面示例所示)。如果您使用龙目岛计划 @Value批注,前面显示的示例DTO将成为 以下:
@Value
@Wither //added - not included in documentation
class NamesOnly {
String firstname, lastname;
}
动态投影到目前为止,我们已将投影类型用作 集合的返回类型或元素类型。但是,您可能想要 选择调用时要使用的类型(这使其成为 动态)。要应用动态投影,请使用查询方法,例如 在以下示例中显示了一个:
示例86.使用动态投影参数的存储库
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}