binaryBigInt
binaryBigInt

Reputation: 1704

Spring Boot - JSON Serialize Custom Object with Array of Custom Objects

There is this class:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private int key;
private String text;
private Tag[] tags;
private String title;
private boolean valid;
public Activity(int key, String text, Tag[] tags, String title) {
    this.key = key;
    this.text = text;
    this.tags = tags;
    this.title = title;
    valid = true;
}

which has an array of Tag associated with it. Tag looks like this:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private long activityId;
private String keyword;

public Tag(String keyword){
    this.keyword = keyword;
    activityId = -1;
}

Both Activity and Tag are Entitys and also both have Repositorys:

public interface TagRepository extends CrudRepository<Tag, Long> {

}

public interface ActivityRepository extends CrudRepository<Activity, Long> {

}

There is this create - method which stores an Activity Object in the database:

  @PostMapping
  public Activity create(@RequestBody Activity input) {
      if(input.getTags() != null) {
          for(Tag t : input.getTags()) {
              t.setActivityId(input.getId()); //associate which activity has which tags
              tagRepository.save(t);
          }
      }

      return activityRepository.save(input);
  }

I transmit this JSON via POST:

{
    "key":2,
    "text":"Hello",
    "tags":[{
        "keyword":"h"
    },{
        "keyword":"b"
    }
    ],
    "title":"world"
}

But I get this error:

"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.orm.jpa.JpaSystemException",
"message": "could not serialize; nested exception is org.hibernate.type.SerializationException: could not serialize"

Both classes have getter/setter for each member variable and also both have default ctors, I just didn't show them here to keep the question as short as possible.

Upvotes: 0

Views: 2468

Answers (1)

Amr Alaa
Amr Alaa

Reputation: 543

First of all you need to create a relationship between activity and tags. Activity has many tags, then the relation should be oneToMany.

http://www.baeldung.com/hibernate-one-to-many

@Entity
@Table(name="ACTIVITY")
public class Activity {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private long id;
  private int key;
  private String text;

  @OneToMany(mappedBy="activity")
  private List<Tag> tags;

  private String title;
  private boolean valid;
  public Activity(int key, String text, List<Tag> tags, String title) {
    this.key = key;
    this.text = text;
    this.tags = tags;
    this.title = title;
    valid = true;
  }
}

@Entity
@Table(name="TAG")
public class Tag {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private long id;

  @ManyToOne
  @JoinColumn(name="activity_id", nullable=false)
  private Activity activity;

  private String keyword;

  public Tag(String keyword){
    this.keyword = keyword;
    activityId = -1;
  }
}

first of all you are not using the property CASCADE.ALL which means that you will handle the save of your tags entity manually.

@PostMapping
  public Activity create(@RequestBody Activity input) {
      if(input.getTags() != null) {
          //you are saving all the nested tags manually before saving the activity
          for(Tag t : input.getTags()) {
              tagRepository.save(t);
          }
      }
      //now you are saving activity which contains these tags
      return activityRepository.save(input);
  }

Upvotes: 1

Related Questions