Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = 'com.flexcodelabs'
version = '0.0.29'
version = '0.0.30'
description = 'Flextuma App'

java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
Expand All @@ -15,12 +16,16 @@ public class JacksonConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
SimpleModule lazyLoadingSafeModule = new SimpleModule()
.setSerializerModifier(new LazyLoadingSafeBeanSerializerModifier());

return JsonMapper.builder()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
.addModule(lazyLoadingSafeModule)
.findAndAddModules()
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.flexcodelabs.flextuma.core.config;

import java.util.List;

import org.hibernate.LazyInitializationException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

public class LazyLoadingSafeBeanSerializerModifier extends BeanSerializerModifier {

@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyWriter> beanProperties) {
return beanProperties.stream()
.map(LazyLoadingSafePropertyWriter::new)
.map(BeanPropertyWriter.class::cast)
.toList();
}

private static final class LazyLoadingSafePropertyWriter extends BeanPropertyWriter {

private LazyLoadingSafePropertyWriter(BeanPropertyWriter base) {
super(base);
}

@Override
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
try {
super.serializeAsField(bean, gen, prov);
} catch (Exception ex) {
if (!isLazyLoadingFailure(ex)) {
throw ex;
}

if (!gen.canOmitFields()) {
super.serializeAsOmittedField(bean, gen, prov);
}
}
}

private boolean isLazyLoadingFailure(Throwable throwable) {
Throwable current = throwable;
while (current != null) {
if (current instanceof LazyInitializationException) {
return true;
}
if (current instanceof JsonMappingException jsonMappingException) {
current = jsonMappingException.getCause();
continue;
}
current = current.getCause();
}
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.hibernate.LazyInitializationException;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -68,4 +69,22 @@ void objectMapper_shouldSerializeEmptyBeanWithoutError() throws JsonProcessingEx
String json = objectMapper.writeValueAsString(bean);
assertEquals("{}", json);
}

static class LazyBean {
public String getName() {
return "test";
}

public Object getLazyRelation() {
throw new LazyInitializationException("no session");
}
}

@Test
void objectMapper_shouldSkipLazyFieldsThatCannotBeInitialized() throws JsonProcessingException {
String json = objectMapper.writeValueAsString(new LazyBean());

assertTrue(json.contains("\"name\":\"test\""));
assertFalse(json.contains("lazyRelation"));
}
}