Search code examples
jsonspring-data-resthateoashal

Spring-Data-REST: Custom serialization of @Embeddable in HAL


I have an entity which looks like this (I'll omit getters, setters and constuctors for the sake of brevity):

@Entity
public class System {
    @NotNull
    @Column(name = "SYSTEMID", nullable = false)
    @Embedded
    private SystemId systemId;
}

with SystemId looking like this:

@Embeddable
@JsonSerialize(using = SystemIdSerializer.class)
@JsonDeserialize(using = SystemIdDeserializer.class)
public class SystemId {
    @Column(name = "SYSTEMID", nullable = false)
    private String value;
}

My custom serializer does nothing but write out value, which works for 'normal' JSON, just not the HAL representation which looks like this:

{
    "systemId": {
        "content": "1"
    }
}

I would like to have it like this

{
    "systemId": "1"
}

as well. Is there any way to do it? I've spent some time googling but wasn't successful. Thanks.


Solution

  • Perhaps the projection can help you...

    @Projection(name="withSystemId", types = System.class)
    public interface WithSystemId {
    
        @JsonProperty("systemId")
        @Value("#{target.systemId.value}")
        String getSysId();
    
        // Other getters of System properties...
    }
    

    Then try GET your System:

    http://localhost:8080/api/systems?projection=withSystemId

    UPDATED

    Concerning the custom serializer - just add @JsonUnwrapped annotation to systemId:

    @Entity
    public class System {
    
        @Embedded
        @JsonUnwrapped
        private SystemId systemId;
    } 
    

    Then you must get what you expect

    {
        "systemId": "1"
    } 
    

    And I assume that your serializer looks like this:

    public class SystemIdSerializer extends StdSerializer<SystemId> {
    
        public SystemIdSerializer() {
            this(null);
        }
    
        protected SystemIdSerializer(Class<SystemId> t) {
            super(t);
        }
    
        @Override
        public void serialize(SystemId id, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeStartObject();
            gen.writeNumberField("systemId", id.value());
            gen.writeEndObject();
        }
    }
    

    Working example is here. See Member and nested MemberSkill classes. Then try to launch the app and GET http://localhost:8080/api/members