Самый простой способ удалить двунаправленные рекурсивные отношения?
Я использую библиотеку Gson для преобразования объектов Java в ответ Json...
проблема заключается в том, что после запросов JPA объект, извлеченный из БД, не может быть преобразован из-за рекурсивной связи с другими объектами (см. мой предыдущий вопрос), например:
public class Gps implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "IMEI", nullable = false, length = 20)
private String imei;
//some code here...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "gpsImei", fetch = FetchType.LAZY)
private List<Coordonnees> coordonneesList;
public class Coordonnees implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "IDCOORDONNEES", nullable = false)
private Integer idcoordonnees;
//some code here...
@JoinColumn(name = "GPS_IMEI", referencedColumnName = "IMEI", nullable = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Gps gpsImei;
Мой исходный код:
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JavaApplication21PU");
GpsJpaController gjc=new GpsJpaController(emf);
Gps gps=gjc.findGps("123456789012345");
for(int i=0;i<gps.getCoordonneesList().size();i++){
gps.getCoordonneesList().get(i).setGpsImei(null);
}
Gson gson=new Gson();
String json=gson.toJson(gps);//convert to json response
System.out.println(json);
Как вы можете видеть здесь, я сделал:
for(int i=0;i<gps.getCoordonneesList().size();i++){
gps.getCoordonneesList().get(i).setGpsImei(null);
}
только для того, чтобы убить рекурсивную взаимосвязь, установив нуль для каждого объекта GPS в списке CoordonneesList.
По-вашему, это хорошее решение или есть другой метод более практичный?
Благодаря
Ответы
Ответ 1
Существует расширение Gson, называемое GraphAdapterBuilder, которое может сериализовать объекты, содержащие циклические ссылки. Здесь очень упрощенный пример из соответствующего тестового примера:
Roshambo rock = new Roshambo("ROCK");
Roshambo scissors = new Roshambo("SCISSORS");
Roshambo paper = new Roshambo("PAPER");
rock.beats = scissors;
scissors.beats = paper;
paper.beats = rock;
GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
.addType(Roshambo.class)
.registerOn(gsonBuilder);
Gson gson = gsonBuilder.create();
System.out.println(gson.toJson(rock));
Отпечатки:
{
'0x1': {'name': 'ROCK', 'beats': '0x2'},
'0x2': {'name': 'SCISSORS', 'beats': '0x3'},
'0x3': {'name': 'PAPER', 'beats': '0x1'}
}
Обратите внимание, что класс GraphAdapterBuilder не включен в gson.jar. Если вы хотите использовать его, вам придется вручную его скопировать в свой проект.
Ответ 2
Я не знаю о Гсоне, но я работаю с Джексоном. Найдите пример использования класса ObjectMapper. Что касается рекурсии, используйте @JsonManagedReference и @JsonBackReference, чтобы остановить это. Посмотрите их, например, на использование.
Ответ 3
Вы можете использовать @Expose (serialize = false), чтобы избежать сериализации коллекции.
Ответ 4
Используйте переходный для игнорирования наборов @OneToMany для google.gson