1

I have a spring JPA entity with numeric properties which should be serialized as string values that are the result of a lookup in a code-list.

@Entity
class Test {
    String name ;
    int status ;   
}

Should be serialized by looking up the numeric value in a code-list like so:

{ "name" : "mytest" , "status" : "APPROVED" }

The code-list is implemented as another entity and can be accessed using a spring-boot JPA repository.

The solution I am looking for must be scalable in that

  • the code-list cannot be loaded from the database again for each serialization or new object
  • the serialization code must be generic so that it can be re-used in other entities.

This is, other entities also have numeric properties and their own corresponding code-list and repository.

I understand one could either use a custom Jackson serializer, or implement the lookup as part of the entity. However, neither seems to satisfy the conditions above. A custom jackson serializer can only have the repository autowired if I share it or the map using a static field. The static field makes it hard to re-use the serializer implementation for other entities. Implementing the lookup as part of the entity, say as custom getter, would make the code hard to re-use, especially since the map for the code-list lookup must be shared across instances.

Update: A third strategy would be to add JPA relationships to the code-list in my entities and to expose the value in a custom getter. For the deserialization rather inefficient lookups would be required, though.

This works, but the static map prevents re-using the code.

@Component
public class NewApprovalSerializer extends JsonSerializer<Integer>
{
    @Autowired
    ApprovalStatusRefRepository repo;

    static Map<Integer, String> map  = new HashMap<Integer,String>() ;

    @PostConstruct
    public void init() {
        for ( TGoApprovalStatusRef as : repo.findAll() ) {
            Integer key = new Integer( as.getApprovalStatusId() );
            String val = as.getNameTx();
            map.put( key   ,  val );
        }               
    }

    public NewApprovalSerializer() { 
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 
    }

    public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException {        
        gen.writeObject( map.get( value  )  );      
    }
}

I could change the entity like such, but I again have a static map and the code is even harder to re-use in another entity.

@Entity
class Test {
    String name ;
    @JsonIgnore
    int status ;

    static Map<Integer, String> map  = new HashMap<Integer,String>() ;


    public Test() {  
       ... init static map
    }

    public String getStatus() {
         return map.get(this.status);
    }
}

What is the standard way to implement a lookup of values uppon serialization (and vice versa in deserialization)?

  • What's your reason for not using an enum (potentially with property accessors on your entity class that do some sort of mapping or conversion to a canonical enum column)? – chrylis -cautiouslyoptimistic- Jan 02 '19 at 18:39
  • @chrylis . I work with a legacy database that models the codelists as separate database tables. I've been thinking of a third approach which would be to include JPA \@OneToMany relationships to the codelists in my entities and to expose the code-list value in a custom getter. Deserialization would require inefficient entity lookups in the getter, though. – kurt-hectic Jan 03 '19 at 13:51

0 Answers0