Shoaib Ahmad
Shoaib Ahmad

Reputation: 141

google Gson causing a stackoverflow

Error    
 07-14 04:33:28.030: E/AndroidRuntime(5216): FATAL EXCEPTION: main
    07-14 04:33:28.030: E/AndroidRuntime(5216): Process: com.tt, PID: 5216
    07-14 04:33:28.030: E/AndroidRuntime(5216): java.lang.StackOverflowError
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.String._getChars(String.java:908)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:147)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:216)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:154)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Game.toString(Game.java:157)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.util.AbstractCollection.toString(AbstractCollection.java:374)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.java:202)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at com.tt.models.Player.toString(Player.java:161)
    07-14 04:33:28.030: E/AndroidRuntime(5216):     at java.lang.StringBuilder.append(StringBuilder.ja

My model player

package com.tt.models;
import java.util.Collection;
import com.google.gson.annotations.SerializedName;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "Player")
public class Player {
    public static final String BATTING_ID_FIELD_NAME = "batting_id";
    public static final String BOWLING_ID_FIELD_NAME = "bowling_id";
    public static final String TEAM_ID_FIELD_NAME = "team_id";
    @SerializedName("__v")
    @DatabaseField(id = true) 
     private int id;

    @SerializedName("_id")
    @DatabaseField(columnName = "_id")
    private String _id;
    /*@SerializedName("__v")
    @DatabaseField(columnName = "__v",id=true)
    private int __v;*/
    @DatabaseField
    private String battingStyle;
    @DatabaseField
    private String bowlingStyle;
    @DatabaseField
    private String dob;
    @DatabaseField
    private String playingRole;
    @DatabaseField
    private String sname;
    @DatabaseField
    private String fname;
    @SerializedName("gallery")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Gallery> gallery;

    @SerializedName("games")
    @ForeignCollectionField(eager = true)
    private Collection<Game> games;

    /*
     * @DatabaseField(dataType = DataType.SERIALIZABLE) private String[] users;
     */
    /*
     * @DatabaseField(dataType = DataType.SERIALIZABLE) private String[] squad;
     */

    Player() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public String getBattingStyle() {
        return battingStyle;
    }

    public void setBattingStyle(String battingStyle) {
        this.battingStyle = battingStyle;
    }

    public String getBowlingStyle() {
        return bowlingStyle;
    }

    public void setBowlingStyle(String bowlingStyle) {
        this.bowlingStyle = bowlingStyle;
    }

    public String getDob() {
        return dob;
    }

    public void setDob(String dob) {
        this.dob = dob;
    }

    public String getPlayingRole() {
        return playingRole;
    }

    public void setPlayingRole(String playingRole) {
        this.playingRole = playingRole;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    /*
     * public String[] getUsers() { return users; }
     * 
     * public void setUsers(String[] users) { this.users = users; }
     */

    /*
     * public String[] getSquad() { return squad; }
     * 
     * public void setSquad(String[] squad) { this.squad = squad; }
     */

    public Collection<Gallery> getGallerys() {
        return gallery;
    }

    public void setGallerys(Collection<Gallery> gallery) {
        this.gallery = gallery;
    }

    public Collection<Gallery> getGallery() {
        return gallery;
    }

    public void setGallery(Collection<Gallery> gallery) {
        this.gallery = gallery;
    }

    public Collection<Game> getGames() {
        return games;
    }

    public void setGames(Collection<Game> games) {
        this.games = games;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    @Override
    public String toString() {
        return "Player [id=" + Integer.toString(id) + ", _id=" + _id + ", battingStyle="
                + battingStyle + ", bowlingStyle=" + bowlingStyle + ", dob="
                + dob + ", playingRole=" + playingRole + ", sname=" + sname
                + ", fname=" + fname + ", gallery=" + gallery + ", games="
                + games + "]";
    }






}
and game model 
package com.tt.models;

import java.util.Collection;

import com.google.gson.annotations.SerializedName;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "Game")
public class Game {
    public static final String INNING_ID_FIELD_NAME = "inning_id";
    public static final String PLAYER_ID_FIELD_NAME = "player_id";
    @SerializedName("__v")
    @DatabaseField(id = true) 
     private int id;

    /*@SerializedName("_id")
    @DatabaseField(columnName = "_id")
    private String _id;
    @SerializedName("__v")
    @DatabaseField(columnName = "__v",id=true)
    private int __v;*/
    @SerializedName("gameType")
    @DatabaseField
    private String gameType;
    @SerializedName("name")
    @DatabaseField
    private String name;
    @SerializedName("totalOvers")
    @DatabaseField
    private String totalOvers;
    @SerializedName("dateStarted")
    @DatabaseField
    private String dateStarted;
    @SerializedName("dateEnded")
    @DatabaseField
    private String dateEnded;
    @SerializedName("innings")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Inning> innings;
    @DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true, columnName = PLAYER_ID_FIELD_NAME)
    private Player player;
    @SerializedName("grounds")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Ground> grounds;
    @SerializedName("teams")
    @ForeignCollectionField(eager = true, maxEagerLevel = 2)
    private Collection<Team> teams;

    public Game() {
        // all persisted classes must define a no-arg constructor with at least
        // package visibility
    }



    /*public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }*/

    public String getGameType() {
        return gameType;
    }

    public int getId() {
        return id;
    }



    public void setId(int id) {
        this.id = id;
    }



    public void setGameType(String gameType) {
        this.gameType = gameType;
    }

    public Collection<Ground> getGrounds() {
        return grounds;
    }

    public void setGrounds(Collection<Ground> grounds) {
        this.grounds = grounds;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDateStarted() {
        return dateStarted;
    }

    public void setDateStarted(String dateStarted) {
        this.dateStarted = dateStarted;
    }

    public String getDateEnded() {
        return dateEnded;
    }

    public void setDateEnded(String dateEnded) {
        this.dateEnded = dateEnded;
    }

    public String getTotalOvers() {
        return totalOvers;
    }

    public void setTotalOvers(String totalOvers) {
        this.totalOvers = totalOvers;
    }

    public Player getPlayer() {
        return player;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    public Collection<Inning> getInnings() {
        return innings;
    }

    public void setInnings(Collection<Inning> innings) {
        this.innings = innings;
    }

    public Collection<Team> getTeams() {
        return teams;
    }

    public void setTeams(Collection<Team> teams) {
        this.teams = teams;
    }



    @Override
    public String toString() {
        return "Game [id=" + Integer.toString(id) + ", gameType=" + gameType + ", name=" + name
                + ", totalOvers=" + totalOvers + ", dateStarted=" + dateStarted
                + ", dateEnded=" + dateEnded + ", innings=" + innings
                + ", player=" + player + ", grounds=" + grounds + ", teams="
                + teams + "]";
    }

    /*public int get__v() {
        return __v;
    }

    public void set__v(int __v) {
        this.__v = __v;
    }*/

Upvotes: 0

Views: 333

Answers (1)

mike_m
mike_m

Reputation: 1546

Player has Game, Game has Player, Player has Game, Game has Player... stackoverflow.

Change the structure of your classes. Eliminate circular references, or use transient keyword on Player or Game reference to exclude it from the serialization.

EDIT:

If you don't want to change the structure of your classes to for example: each Game has reference to the Player, but the Player doesn't have references to his Games. Then you may do something like this:

  • serialize the Player
  • Player will serialize its Games collection
  • the Game class should have privatetransientPlayer player; field, to avoid StackOverflowError
  • After deserialization the Player should iterate over its Games and call game.setPlayer(this); on each of them

Also you need fix your toString() methods. Because Player class's toString() method calls Game class's toString() which calls Player class's toString().

When you get StackOverflowError just look for things like this. Or don't build class structures like this, where each Player has his Games, and each Game has its Player.

Upvotes: 4

Related Questions