Problem
I am trying to have Jackson
set any Empty String
to null
this is within a Spring-boot
Application. We have added validation to our POJO to check to see that the value is between 1 and 255 IFF the value is being set.
@Size(min = 1, max = 255)
@Column(length = 255)
private String businessTitle;
The problem is that when a Empty String
is passed to the validation it will fail with a javax.validation.ConstraintViolationException
exception because it is checking the empty string.
I tried to setup DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
on the Jackson2ObjectMapperBuilder
so it would set these empty strings as null and the validation would not fail. This is not happening though, it continues to pass the Empty String
into the save()
for the Object.
Question
What is going wrong or needs to be adjusted to have the Empty String
set correctly to null
when saving the Ojbject?
Code
Object
@Size(min = 1, max = 255)
@Column(length = 255)
private String businessTitle;
JacksonConfiguration
@Configuration
public class JacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilder filteringObjectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.featuresToEnable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
return builder;
}
}
Exception
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com..model.User] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='size must be between 1 and 255', propertyPath=businessTitle, rootBeanClass=class com..model.User, messageTemplate='{javax.validation.constraints.Size.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:86)
at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:244)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:118)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
... 127 common frames omitted
DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
is not going to help you because it means "deserialise empty string JSON value as null for object field" and unfortunately your String fields are scalars not JSON objects. I think there is no convenient way to get behaviour you want. It is possible to override deserializaton behaviour for all fields with type String but you may not want it. Also you can define custom deserialzer but you will need to annotate every field like this:
@JsonDeserialize(using = MyStringDeseralizer.class)
private String businessTitle;
where class MyStringDeseralizer extends JsonDeserializer<String>
and implement conversion logic you need.
Actually there is a better solution then having to put it on each attribute. Create a custom deserializer, EmptyToNullStringDeserializer
, for changing '' to null. This is based on a co-workers solution.
builder
.deserializerByType(String.class, new EmptyToNullStringDeserializer());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.