Issue
I'm using spring-boot to provide a REST interface persisted with MongoDB. I'm using the 'standard' dependencies to power it, including spring-boot-starter-data-mongodb
and spring-boot-starter-web
.
However, in some of my classes I have fields that I annotate @Transient
so that MongoDB does not persist that information. However, this information I DO want sent out in my rest services. Unfortunately, both MongoDB and the rest controller seem to share that annotation. So when my front-end receives the JSON object, those fields are not instantiated (but still declared). Removing the annotation allows the fields to come through in the JSON object.
How I do configure what is transient for MongoDB and REST separately?
Here is my class
package com.clashalytics.domain.building;
import com.clashalytics.domain.building.constants.BuildingConstants;
import com.clashalytics.domain.building.constants.BuildingType;
import com.google.common.base.Objects;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import java.util.*;
public class Building {
@Id
private int id;
private BuildingType buildingType;
private int level;
private Location location;
// TODO http://stackoverflow.com/questions/30970717/specify-field-is-transient-for-mongodb-but-not-for-restcontroller
@Transient
private int hp;
@Transient
private BuildingDefense defenses;
private static Map<Building,Building> buildings = new HashMap<>();
public Building(){}
public Building(BuildingType buildingType, int level){
this.buildingType = buildingType;
this.level = level;
if(BuildingConstants.hpMap.containsKey(buildingType))
this.hp = BuildingConstants.hpMap.get(buildingType).get(level - 1);
this.defenses = BuildingDefense.get(buildingType, level);
}
public static Building get(BuildingType townHall, int level) {
Building newCandidate = new Building(townHall,level);
if (buildings.containsKey(newCandidate)){
return buildings.get(newCandidate);
}
buildings.put(newCandidate,newCandidate);
return newCandidate;
}
public int getId() {
return id;
}
public String getName(){
return buildingType.getName();
}
public BuildingType getBuildingType() {
return buildingType;
}
public int getHp() {
return hp;
}
public int getLevel() {
return level;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public BuildingDefense getDefenses() {
return defenses;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Building building = (Building) o;
return Objects.equal(id, building.id) &&
Objects.equal(hp, building.hp) &&
Objects.equal(level, building.level) &&
Objects.equal(buildingType, building.buildingType) &&
Objects.equal(defenses, building.defenses) &&
Objects.equal(location, building.location);
}
@Override
public int hashCode() {
return Objects.hashCode(id, buildingType, hp, level, defenses, location);
}
}
As is, hp
and defenses
show up as 0
and null
respectively. If I remove the @Transient
tag it comes through.
Solution
I solved by using @JsonSerialize. Optionally you can also opt for @JsonDeserialize if you want this to be deserailized as well.
@Entity
public class Article {
@Column(name = "title")
private String title;
@Transient
@JsonSerialize
@JsonDeserialize
private Boolean testing;
}
// No annotations needed here
public Boolean getTesting() {
return testing;
}
public void setTesting(Boolean testing) {
this.testing = testing;
}
Answered By - sheetal