spring-projects / spring-projects/spring-data-mongodb

Deserializing enums as interfaces with Spring Data MongoDB [DATAMONGO-1884]

Open
#2,786 2 comments 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 30, 2020.

in: mapping type: bug
Dominant language
Java
Stars
1.7k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

Joaquin Peñalver opened DATAMONGO-1884 and commented

I've currently a problem with serialize/deserialize process in MongoDB of an object that contains an attribute defined by a marker interface and the implementations of this interface are Enums.

My used versions are Spring Boot 1.5.2, Spring 4.3.7 and Spring-data-mongodb 1.10.1.

The piece of code afected is:

public interface EventType {
    String getName(); 
}
public interface DomainEvent extends Serializable {

    UUID getId();    
    LocalDateTime getOccurredOn();    
    EventType getEventType();    
    String getEventName();    
}
public abstract class AbstractDomainEvent implements DomainEvent {

    private UUID id;
    private LocalDateTime occurredOn;
    private EventType eventType;

    protected AbstractDomainEvent(EventType eventType) {
        this.id = UUID.randomUUID();
        this.occurredOn = LocalDateTime.now();
        this.eventType = eventType;
    }
}
public class MyEventOne extends AbstractDomainEvent {

    private Object myConcreteData;

    public MyEventOne(Object data) {

        super(MyEventType.EVENT_ONE);
        this.myConcreteData = data;
    }    
}
public enum MyEventType implements EventType {

    EVENT_ONE,
    EVENT_N;

    @Override
    public String getName() {
        return this.name();
    }    
}

Ok, well. My problem is when I try to deserialize an event persisted in mongoDB.

When I persist MyEventOne, Spring data mongo persist the object as:

{
    "_class" : "xxx.xxx.xxx.MyEventOne",
    "_id" : LUUID("d74478e7-258c-52c4-4fc5-aba20a30d4b6"),
    "occurredOn" : ISODate("2018-02-21T14:39:53.549Z"),
    "eventType" : "EVENT_ONE"
}

Note the eventType is serialized as String, I know that String is the default representation of a Enum (real class), but in this case is referenced as a interface EventType in AbstractDomainEvent.

When I try to read this document, I have this exception:

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [xxx.xxx.xxx.EventType]

Any idea? May be it's a bug? May be spring-data-mongo should resolve this situation inserting a metadata information about the concrete Enum instance, like a "_class" field?

I try insert @JsonTypeInfo annotation in EventType attribute at AbstractDomainEvent but it doesnt works, i think that it's ignored.

The temporary solution might be write a custom converter, but i think that this feature can be a framework feature.

Thanks in advcance!


Reference URL: https://stackoverflow.com/questions/48910761/deserializing-interfaces-with-spring-data-mongodb

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.