Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hibernate4Module causes Type Erasure #81

Closed
agorina opened this issue Dec 28, 2015 · 8 comments
Closed

Hibernate4Module causes Type Erasure #81

agorina opened this issue Dec 28, 2015 · 8 comments
Milestone

Comments

@agorina
Copy link

agorina commented Dec 28, 2015

I have an object that contains the following object that in turn has a collection of polymorphic objects.

public class RecordFilters implements RecordFilter {
    @XmlElementRef
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
    @JsonSubTypes({ @JsonSubTypes.Type(value = EmptyRecordFilter.class),
                    @JsonSubTypes.Type(value = RangeRecordFilter.class) })
    private List<AbstractRecordFilter> filters;
...

Without registering Hibernate4Module, I am able to serialize/deserialize the parent object with all its children.

Calling registerModule with Hibernate4Module causes the failure.

final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Hibernate4Module());

When I examine the difference, I can see that with Hibernate4Module being registered, the serialized object is missing @type for objects within RecordFilter.

@cowtowncoder
Copy link
Member

I would need a reproduction of this (ideally unit test); above is not enough to trigger the issue.

@agorina
Copy link
Author

agorina commented Dec 28, 2015

Let me know if this is enough:

public interface RecordFilter {
}
public abstract class AbstractRecordFilter implements RecordFilter {
}
@XmlRootElement(name="emptyRecordFilter")
@XmlAccessorType(XmlAccessType.FIELD)
@JsonTypeName(value="emptyRecordFilter")
public class EmptyRecordFilter extends AbstractRecordFilter {
    private Expression expr;

    EmptyRecordFilter() {
    }

    public EmptyRecordFilter(Expression expr) {
        this.expr = expr;
    }
}
public class Expression {
    @XmlValue
    private String expression;

    Expression() {
    }

    public Expression(String expression) {
        this.expression = expression;
    }

    public String getExpression() {
        return expression;
    }

    public static Expression simpleFieldExpression(String field) {
        return new Expression("${" + field + "}");
    }
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class BaseLayout {
    private RecordFilters recordFilters;

    public RecordFilters getRecordFilters() {
        return recordFilters;
    }

    public BaseLayout addRecordFilter(AbstractRecordFilter recordFilter) {
        if (recordFilters == null) {
            recordFilters = new RecordFilters();
        }
        recordFilters.add(recordFilter);
        return this;
    }
}
@XmlRootElement(name="testLayout")
@XmlAccessorType(XmlAccessType.FIELD)
@JsonTypeName(value="testLayout")
public class TestLayout extends BaseLayout {
}
    @Test
    public void test() throws Exception {
        final TestLayout layout = new TestLayout();
        layout.addRecordFilter(new EmptyRecordFilter(Expression.simpleFieldExpression("id")));

        final ObjectMapper mapper = new ObjectMapper();

        // uncomment the line below to see the problem
        // mapper.registerModule(new Hibernate4Module());

        final StringWriter writer = new StringWriter();
        try {
            mapper.writerWithDefaultPrettyPrinter().writeValue(writer, layout);
        } catch (IOException e) {
            fail(e.getMessage());
        }
        final String text = writer.toString();
        System.out.println(text);

        final TestLayout restoredLayout =
            mapper.reader(TestLayout.class).readValue(text);

    }

Without Hibernate4Module the serialized value looks like this:

{
  "recordFilters" : {
    "filters" : [ {
      "@type" : "emptyRecordFilter"
    } ]
  }
}

but with the Hibernate4Module it is:

{
  "recordFilters" : {
    "filters" : [ { } ]
  }
}

Excerpt from pom.xml: (note I have tried with using the same version 2.6.1 for all of them and the issues is still here)

 <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.4.3</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.6.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-hibernate4</artifactId>
      <version>2.6.1</version>
    </dependency>

@cowtowncoder
Copy link
Member

@agorina Thank you -- I'll have a look; should be enough. I will use consistent version for all components for testing.

@cowtowncoder
Copy link
Member

Ok, yes, I can reproduce the issue.

@cowtowncoder cowtowncoder added this to the 2.7.0-rc3 milestone Jan 4, 2016
@cowtowncoder
Copy link
Member

Looks like type handler was not being passed properly; needed rather sizable changes so can only be done for 2.7. Will be included in 2.7.0 when it is released soon.

@agorina
Copy link
Author

agorina commented Jan 4, 2016

Thank you! Could you please let me know the estimated timeline for 2.7.0 release?

@cowtowncoder
Copy link
Member

Within 2 weeks, mid-january or earlier.

@agorina
Copy link
Author

agorina commented Jan 4, 2016

Thank you for a prompt response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants