1

I'm trying to transform this class below using the Gson.ToJson(Object) method, but it is returing me the object hash code of the class, eg: br.com.helpradar.entity.User@475fdaaa

However, I can retrieve the user.expertise without any problems and with all the relationships: Gson.ToJson(user.getExpertise)

@Entity
@SequenceGenerator(name="seqUser", sequenceName="SEQ_USER", allocationSize=1)
public class User {
@Id
private Long id;

@Column(nullable=false)
private String name;

@OneToOne
private Contact contact;

//enum
private TypeUser typeUser;

@ManyToMany(cascade = { CascadeType.ALL })  
@JoinTable(name = "USER_REVIEW", 
joinColumns = { @JoinColumn(name = "USER_ID") },
inverseJoinColumns = { @JoinColumn(name = "REVIEW_ID") })  
@Column(name="REVIEW")
private Set<Review> review= new HashSet<Review>();

@ManyToMany(cascade = { CascadeType.ALL })  
@JoinTable(name = "USER_EXPERTISE", 
joinColumns = { @JoinColumn(name = "USER_ID") },
inverseJoinColumns = { @JoinColumn(name = "EXPERTISE_ID") })  
@Column(name="EXPERTISE")
private Set<Expertise> expertise = new HashSet<Expertise>();
}

This is my Gson method:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(User.class, new MyTypeAdapter<Expertise>())
    .registerTypeAdapter(User.class, new MyTypeAdapter<Review>())

    .create();

return gson.toJson(user);

This is my MyTypeAdapter:

class MyTypeAdapter<T> extends TypeAdapter<T> {
public T read(JsonReader reader) throws IOException {
    return null;
}

public void write(JsonWriter writer, T obj) throws IOException {
    if (obj == null) {
        writer.nullValue();
        return;
    }
    writer.value(obj.toString());
}

}

So, how do I get the Gson.ToJson(user) to actually return a Json string so that I can use Gson.FromJson on my other end? Thanks in advance.

VyMajoris
  • 66
  • 12
  • Why do you have type adapters? Why are you writing the output of `toString` to the `JsonWriter`? – Sotirios Delimanolis Oct 15 '14 at 04:56
  • @SotiriosDelimanolis Without the type adapters the Gson gives me a StackOverFlow. The output of gson.ToJson(user) is the return of a Restfull method. – VyMajoris Oct 15 '14 at 05:00
  • Do `Review` objects have backreferences to their `User`? – Sotirios Delimanolis Oct 15 '14 at 05:01
  • Do you know how a `toString` method works? Its purpose? – Sotirios Delimanolis Oct 15 '14 at 05:01
  • Yes. However, I don't really need the Type Adapter on the Review Object. I tested it without it and it didn't gave me StackOverFlow. Only the Expertise without the Type Adapter gives me StackOverFlow. – VyMajoris Oct 15 '14 at 05:03
  • No, I don't really know how the ToString works. I just got this snippet from the internet – VyMajoris Oct 15 '14 at 05:04
  • 1
    That's a dangerous game. Read [here](http://stackoverflow.com/questions/3615721/how-to-use-the-tostring-method-in-java). – Sotirios Delimanolis Oct 15 '14 at 05:05
  • Then you should read up on the purpose of a `TypeAdapter`. If you're writing your own, you have to do the full serialization/deserialization yourself. – Sotirios Delimanolis Oct 15 '14 at 05:05
  • @VyMajoris: the reason Sotirios Delimanolis keeps harping about "toString()" - is that's precisely what's causing output like "br.com.helpradar.entity.User@475fdaaa". – FoggyDay Oct 15 '14 at 05:13
  • BTW, the 475fdaaa in `br.com.helpradar.entity.User@475fdaaa` is _not_ the address. It's the object's identity hash code. Why is this distinction important? Because heap objects in the JVM are frequently moved by the garbage collector, so very few objects retain a constant address. But the identity hash code stays the same for the life of the object. – C. K. Young Oct 15 '14 at 05:16
  • @FoggyDay I'm starting to notice that. But how I can I change it? The `writer.value()` only accepts primitives! – VyMajoris Oct 15 '14 at 05:19

1 Answers1

2

I think you need use method enableComplexMapKeySerialization(). Here you can see next documentation:

public GsonBuilder enableComplexMapKeySerialization()

Enabling this feature will only change the serialized form if the map 
key is a complex type (i.e. non-primitive) in its serialized JSON form. 
The default implementation of map serialization uses toString() on the key...

And example:

Gson gson = new GsonBuilder()
   .register(Point.class, new MyPointTypeAdapter())
   .enableComplexMapKeySerialization()
   .create();

Map<Point, String> original = new LinkedHashMap<Point, String>();
original.put(new Point(5, 6), "a");
original.put(new Point(8, 8), "b");
System.out.println(gson.toJson(original, type));

Output will be:

{
     "(5,6)": "a",
     "(8,8)": "b"
}

So, you can try like this:

Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new MyTypeAdapter<Expertise>())
.registerTypeAdapter(User.class, new MyTypeAdapter<Review>())
.enableComplexMapKeySerialization()
.create();
0xFF
  • 585
  • 1
  • 6
  • 22
  • I'm sorry, no results. I also do not have implemented the _Serializable_ interface on my User class. Maybe this is the problem? – VyMajoris Oct 15 '14 at 05:21
  • Try add _Serializable_ interface, whats problems? If it'll be work don't forget add a _private static final long serialVersionID_ on your User class. – 0xFF Oct 15 '14 at 05:50
  • Yeah... Sorry for the delay, but it still the same. For now I'll just decompose the proprieties of the User object and then form another Json step-by-step or something. – VyMajoris Oct 15 '14 at 06:23
  • Override the _toString()_ method. It should print your User class as JSON array. I think after this manipulations you'll have a right output in all program. – 0xFF Oct 15 '14 at 06:33