无法将自定义类型存储在数据库中-JSON字符串-Java.lang.illegalargumentException:无法将最终字段设置为java.util.linkedhashmap
我在JPA实体中使用自定义类型有问题,然后将其转换为JSON字符串中的数据库。
这是基本JPA实体:折扣(我们正在使用Lombok和构建器来创建对象实例。此问题发生在类型局部化文本的两个字段上):
@Value
@NoArgsConstructor(force = true)
@AllArgsConstructor
@Builder(builderMethodName = "internalBuilder")
@Entity
@Table(name="discount")
public class Discount {
@Id
@Column(name = "ID", nullable = false, unique = true)
@Type(type="uuid-char")
UUID id;
@Column(name="NO", nullable = false, unique = true)
String no;
@Column(name="I_NO", nullable = false, unique = true)
Integer iNo;
@Convert(converter = JpaJsonConverter.class)
@Column(name="DESIGNATION", nullable = false)
LocalizedTexts designation;
@Convert(converter = JpaJsonConverter.class)
@Column(name="PRINT_TEXT")
LocalizedTexts printText;
...
/**
* Builder with required parameters
*/
public static Discount.DiscountBuilder builder(UUID id, String no, LocalizedTexts designation) {
return internalBuilder()
.id(id)
.no(no)
.designation(designation);
}
// Getters
...
}
我使用属性转换器来转换自定义类型(扩展Map<对象,字符串):
@Converter
public class JpaJsonConverter implements AttributeConverter<Object, String> {
private final static ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(Object localizedTexts) {
String localizedTextsJson = null;
try {
localizedTextsJson = objectMapper.writeValueAsString(localizedTexts);
} catch (JsonProcessingException ex) {
//throw new RuntimeException();
}
return localizedTextsJson;
}
@Override
public Object convertToEntityAttribute(String localizedTextsJSON) {
Object localizedTexts = null;
try {
localizedTexts = objectMapper.readValue(localizedTextsJSON, Object.class);
} catch (IOException ex) {
//throw new RuntimeException();
}
return localizedTexts;
}
}
这是自定义类型:本地化texxts(map&lt; enum,string&gt;):
public class LocalizedTexts extends HashMap<Language, String> implements EntityBase {
public LocalizedTexts() {
}
public LocalizedTexts(Map map) {
this.putAll(map);
}
public static LocalizedTextsBuilder internalBuilder() {
return new LocalizedTextsBuilder();
}
public static class LocalizedTextsBuilder {
LocalizedTextsBuilder() {
}
public LocalizedTexts build() {
return new LocalizedTexts();
}
public String toString() {
return "LocalizedTexts.LocalizedTextsBuilder()";
}
}
}
当我试图将折扣对象保存到数据库中时,问题发生了:
...
discountRepository.save(discount);
...
我已经检查了且属性转换器按预期工作(变换局部化teminizedtexts to JSON弦)。我得到的例外的完整堆栈痕迹如下:
org.springframework.orm.jpa.JpaSystemException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation; nested exception is org.hibernate.PropertyAccessException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy116.save(Unknown Source)
at net.xxxxx.yyyyy.svc_voucher.messagehandler.DiscountHandler.handleCommand(DiscountHandler.java:58)
at net.xxxxx.yyyyy.svc_voucher.handlers.TestDiscountHandler.Sending_script_to_messageHandler_handleCommand(TestDiscountHandler.java:109)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
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:366)
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$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
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$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.hibernate.PropertyAccessException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:72)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:681)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:144)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:5252)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:498)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:241)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:829)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at jdk.proxy2/jdk.proxy2.$Proxy113.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:650)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 42 more
Caused by: java.lang.IllegalArgumentException: Can not set final net.xxxxx.yyyyy.entity.internal.LocalizedTexts field net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation to java.util.LinkedHashMap
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:83)
at java.base/java.lang.reflect.Field.set(Field.java:799)
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:52)
... 81 more
I have a problem using a custom type into my JPA entity and then convert and store it into the database as JSON string.
Here is the base JPA entity: Discount (We are using Lombok and builders for creating object instances. The issue occurs on the two fields of type LocalizedTexts):
@Value
@NoArgsConstructor(force = true)
@AllArgsConstructor
@Builder(builderMethodName = "internalBuilder")
@Entity
@Table(name="discount")
public class Discount {
@Id
@Column(name = "ID", nullable = false, unique = true)
@Type(type="uuid-char")
UUID id;
@Column(name="NO", nullable = false, unique = true)
String no;
@Column(name="I_NO", nullable = false, unique = true)
Integer iNo;
@Convert(converter = JpaJsonConverter.class)
@Column(name="DESIGNATION", nullable = false)
LocalizedTexts designation;
@Convert(converter = JpaJsonConverter.class)
@Column(name="PRINT_TEXT")
LocalizedTexts printText;
...
/**
* Builder with required parameters
*/
public static Discount.DiscountBuilder builder(UUID id, String no, LocalizedTexts designation) {
return internalBuilder()
.id(id)
.no(no)
.designation(designation);
}
// Getters
...
}
I am using an Attribute converter to transform the custom type (extending a Map<Object, String):
@Converter
public class JpaJsonConverter implements AttributeConverter<Object, String> {
private final static ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(Object localizedTexts) {
String localizedTextsJson = null;
try {
localizedTextsJson = objectMapper.writeValueAsString(localizedTexts);
} catch (JsonProcessingException ex) {
//throw new RuntimeException();
}
return localizedTextsJson;
}
@Override
public Object convertToEntityAttribute(String localizedTextsJSON) {
Object localizedTexts = null;
try {
localizedTexts = objectMapper.readValue(localizedTextsJSON, Object.class);
} catch (IOException ex) {
//throw new RuntimeException();
}
return localizedTexts;
}
}
And here is the custom type: LocalizedTexts (Map<Enum,String>):
public class LocalizedTexts extends HashMap<Language, String> implements EntityBase {
public LocalizedTexts() {
}
public LocalizedTexts(Map map) {
this.putAll(map);
}
public static LocalizedTextsBuilder internalBuilder() {
return new LocalizedTextsBuilder();
}
public static class LocalizedTextsBuilder {
LocalizedTextsBuilder() {
}
public LocalizedTexts build() {
return new LocalizedTexts();
}
public String toString() {
return "LocalizedTexts.LocalizedTextsBuilder()";
}
}
}
The issue occurs when I am trying to save a Discount object into the database:
...
discountRepository.save(discount);
...
I have checked and the attribute converter works as expected (transform LocalizedTexts into JSON strings). The full stack trace of the exception I get is the following:
org.springframework.orm.jpa.JpaSystemException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation; nested exception is org.hibernate.PropertyAccessException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy116.save(Unknown Source)
at net.xxxxx.yyyyy.svc_voucher.messagehandler.DiscountHandler.handleCommand(DiscountHandler.java:58)
at net.xxxxx.yyyyy.svc_voucher.handlers.TestDiscountHandler.Sending_script_to_messageHandler_handleCommand(TestDiscountHandler.java:109)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
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:366)
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$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
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$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.hibernate.PropertyAccessException: Could not set field value [{de=Rabatt 1, en=Discount 1}] value by reflection : [class net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation] setter of net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:72)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:681)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:144)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:5252)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:498)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:241)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:829)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at jdk.proxy2/jdk.proxy2.$Proxy113.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:650)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 42 more
Caused by: java.lang.IllegalArgumentException: Can not set final net.xxxxx.yyyyy.entity.internal.LocalizedTexts field net.xxxxx.yyyyy.svc_voucher.entity.Discount.designation to java.util.LinkedHashMap
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:83)
at java.base/java.lang.reflect.Field.set(Field.java:799)
at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:52)
... 81 more
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
起初,人们可以相信
最终
修饰符是造成问题的原因,但实际上不是。让我们尝试以下简单的测试:
我们得到:
这是不是您遇到的错误(您的stackTrace显示
IllegalArgumentException
,而不是Illegalacccessexception
) 。让我们更改代码以添加
setAccessible(true)
:这次起作用,没有例外。
现在,让我们用
1
“ 1”
:我们得到:
这次这与您的错误完全相同。
IllegalArgumentException
表示我们正在尝试将不兼容的值分配(此处,String
integer )。您的stacktrace说,您正在尝试将
linkedHashmap
分配给指定
字段,这确实是不兼容的(名称
是aboce> intaborized> localizedTexts
)。要了解
linkedHashmap
来自何处,让我们看一下您的jpajsonConverter
。负责将JSON字符串转换为本地化texts
对象的方法是:您正在使用包含对象的JSON字符串和
object.class。
作为第二个参数。在这种情况下,杰克逊返回
linkedhashmap
。它无法知道您想要entainizedTexts
。这是修复该方法的可能方法:
At first it's tempting to believe that the
final
modifier is the cause of the issue, but in fact it's not.Let's try this simple test:
We get:
This is not the error that you are getting (your stacktrace shows an
IllegalArgumentException
, not anIllegalAccessException
).Let's change the code to add a
setAccessible(true)
:This time it works, no exception is thrown.
Now let's replace the
1
with"1"
:We get:
This time this is exactly the same error as yours. The
IllegalArgumentException
means that we're trying to assign an incompatible value (here, aString
to anInteger
).Your stacktrace says that you're trying to assign a
LinkedHashMap
to thedesignation
field, which is incompatible indeed (designation
being aLocalizedTexts
).To understand where the
LinkedHashMap
comes from, let's take a look at yourJpaJsonConverter
. The method responsible for converting a JSON string to aLocalizedTexts
object is:You're calling
readValue()
with a JSON string containing an object, andObject.class
as second argument.In such a case, Jackson returns a
LinkedHashMap
. It has no way to know that you want aLocalizedTexts
.Here is a possible way to fix the method:
我遵循并复制了您的代码,因此让我们通过了解根本原因来谈论问题。
首先,您需要阅读
stacktrace/登录
我们读到我们无法设置final final the final of finalararymumentException向我们展示的字段。第二个例外,第一个例外说明了第一个的东西,但更通用。
第二,我们必须知道我们在
entity
上使用的注释和库在这种情况下是折扣
,而不是通过添加来添加,而是在通过阅读官方文档来使用。因此,您确保使用什么。通过使用
@value
折扣
的每个字段都是私人和最终的,因此指定指定
nes final不会修改我们无法修改我们无法进行的设置任何字段,以确保我发布的内容,您可以阅读以下文档。@value lombok文档说:
通过删除
@Value
解决问题,这是不必要的。I followed and reproduced your code, so let's talk about the issue by understanding the root cause.
First, you need to have a reading of
stacktrace/logging
we read that we can't set final a field which IllegalArumentException shows us.and second exception wrapped by the first one says something seemed to the first one but more generic.
Second, we must know what annotations and library we use on our
Entity
in this case isDiscount
, not adding by adding, but knowing it before to use by reading the official documentation. so you make sure what you use.By using
@Value
each field ofDiscount
is made private and final, so pointingdesignation
as final won't be modified which we can't set any field, to ensure what I am posting you can read the documentation below.The @Value lombok documentation says:
The issue was resolved by removing
@Value
which is not necessary have it.