0

I have these two base classes:

class BasePost {
   private String id;
   private String creator;
   private BasePostMeta postMeta;
}

class BasePostMeta {
   private String title;
   private String content;
}

And some other that extending them:

class ProjectPost extends BasePost {
    private ProjectPostMeta postMeta;
}

class ProjectPostMeta extends BasePostMeta {
    private String startDate;
    private String endDate;
}

As you can see I will hide the postMeta if I need.

When I tried to serialize it with GSON, I got "multiple fields" warning for postMeta. I've looked into this answer utilizing ExclusionStrategy but it hides the subclass field in favor of superclass field.

How to achieve the other way around?

Community
  • 1
  • 1
Fadli
  • 976
  • 9
  • 24
  • Declare the field you want to exclude as `transient`, it will not be serialized. – Jean-Baptiste Yunès Apr 02 '16 at 07:09
  • @Jean-BaptisteYunès I don't want to do that because it will always make it not serialized. Sometimes I want to hide BasePostMeta but sometimes I don't because the base one will suffice in another subclass of BasePost. – Fadli Apr 02 '16 at 07:13
  • Then write your own serializer... I general either you want to serialize a field or not, but not both. If you really want, derived BasePostMeta in two sub classes, one with all fields transient the other not, rename the postMeta field to something else to avoid conflicts and dynamically choose which subclass to instanciate for the field. – Jean-Baptiste Yunès Apr 02 '16 at 07:16
  • @Jean-BaptisteYunès by deriving into two sub classes I would not be able to pass it to a general function that accepts BasePostMeta since there are two derived class thus I need two general function that accepts each of them. Unless two of the classes implements an interface which has `getPostMeta` Writing my own serializer seems not worth the effort for now. But many thanks! – Fadli Apr 02 '16 at 07:33
  • I think you shall read something about polymorphism... – Jean-Baptiste Yunès Apr 02 '16 at 09:08

1 Answers1

0

Try to use generics and the type parameter. Let's say your base class will be:

public class AbstractPost<T> {
  private T postMeta;
}

The BasePost can be changed to:

public class BasePost<BasePostMeta> {
  private BasePostMeta postMeta;
}

and ProjectPost to:

public class ProjectPost<ProjectPostMeta> {
  private ProjectPostMeta postMeta;
}

This way you'll only have one field called postMeta and Gson should be able to figure out its type.

Egor
  • 39,695
  • 10
  • 113
  • 130
  • You're the man. Why didn't think of generic. One problem that I would foresee in the future: If there are many fields like this, say 5 then it would be 5 generics type. But it does work. – Fadli Apr 02 '16 at 07:27
  • Indeed. The solution would probably be to separate data and domain entities, use whatever suits your JSON format for data entities and then turn these entities into meaningful domain objects. There you'll have a lot more flexibility with how you structure the data. – Egor Apr 02 '16 at 07:33