Search code examples
jakarta-eeserializationcdijboss-weldweld

Can't serialize (json) object because weld creates a proxy "Unrecognized field "handler"


I have many DTO classes i my project that are serialize to json to be used for rest endpoints. All extend (direct or indirect) an abstract class "Linkable" that holds the id of the objects and creates self link using injected "UriInfo". To get this working i need to inject instances of the DTOs. This all works fine.

Lately i created 2 other DTO that have an additional level in hierarchy. The problem is that if i try to inject instances of this classes i get an proxy (created by weld). This proxies contain aditional fields that can't be serialize because they are unknown (no getters or setters): com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "handler"

So my question is: Why a proxy is instantiated and not the class itself. As a workaround: can i mark thos additional fields to be ignored somehow (the proxy is a subclass)?

Here is the code of the part of the hierarchy different to the working DTOs (CreatedByUserRepresentation extends Linkable):

public abstract class VoteRepresentation<T extends CreatedByUserRepresentation> extends CreatedByUserRepresentation{

    @NotNull
    private T voteOf;

    @Min(-1) // down vote
    @Max(1) // up vote
    private int value;

    @AssertTrue
    public boolean valueIsNotZero() {
        return value != 0;
    }

    public T getVoteOf() {
        return voteOf;
    }

    public int getValue() {
        return value;
    }

    public void setVoteOf(T voteOf) {
        this.voteOf = voteOf;
    }

    public void setValue(int value) {
        this.value = value;
    }

}

The actual class:

@XmlRootElement(name = "problemvote", namespace = "urn:problems:problemvote")
public class ProblemVoteRepresentation extends VoteRepresentation<ProblemRepresentation> {

    @Override
    protected Class<?> getResourceClass() {
        return ProblemVoteResource.class;
    }
}

There is another extension of "VoteRepresentation". Both have same Problem: Via cdi i can only obtain "proxy" instances with additional fields not serializable. It would be enough to get some clues why sometime a proxy is used. I only read about the scope. but in this case the class that injects the dto are all "RequestScoped".


Solution

  • I found the cause of this odd behavior: It is the annotation @AssertTrue. If i remove it weld no longer uses a proxy and serialization works fine.

    This limits usage of javax.validation a lot and i think this behavior is not intended?!

    EDIT Martin Kouba gave a good explanation this behavior is implied by the bean validation spec 10.1.2.