'enforce enum serialization with a spring jpa projection?
Say I have the following JPA entity, with an enum field ON/OFF mapped to an SQL enum("on", "off").
@Entity
public class Process {
@Id
private Long Id;
@Convert(converter = StatusConverter.class)
private Status status;
// getter/setter omitted
}
public enum Status {
ON("on"),
OFF("off");
private final String status;
Status(String status) {
this.status = status;
}
// JSON (de)serialization
@JsonCreator
public static Status decode(String status) {
return valueOf(status.toUpperCase());
}
@JsonValue
public getStatus() {
return status;
}
// DAO layer conversion
public String toDatabaseColumn() {
return this.name().toLowerCase();
}
}
@Converter
public class StatusConverter implements AttributeConverter<Status, String> {
@Override
public String convertToDatabaseColumn(Status attribute) {
return attribute.toDatabaseColumn();
}
@Override
public Status convertToEntityAttribute(String dbData) {
return Status.decode(dbData);
}
}
// Spring JPA projection
public interface ProcessSummary {
String getStatus();
}
// a minimalist JPA repository
public interface ProcessRepository extends Repository<Process, Long> {
<T> T findById(Long id, Class<T> type;
}
If I use repository.findById(1L, Process.class) in a REST controller, both the DAO layer conversion and the JSON serialization work as expected :
- my database record has its status set to
on - it is mapped to the Java
Status.ON - the entity is serialized as
{
"status" : "on"
}
But if I use repository.findById(1L, ProcessSummary.class) instead, the entity is serialized as
{
"status" : "ON"
}
How can I get the same result when using a projection as target type? Is it possible with a projection, or should I try something else (a DTO class maybe)?
Solution 1:[1]
Sorry folks, it was just me and a textbook case of of PEBKAC :)
The getStatus() method in the interface MUST return a Status, not a String.
public interface ProcessSummary {
String getStatus();
}
does what it's asked: converts the enum to a String, hence Status.ON is serialized as "ON", while
public interface ProcessSummary {
Status getStatus();
}
indeed uses the @JsonValue annotated method and serializes Status.ON as "on".
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Marc Tarin |
