Всем привет. И сразу же ВОПРОС: Как конвертировать List to Json
Если конвертирую один обьект Car в Json-obj то все хорошо
Car cars = carSrv.getById(1);
Gson gson = new GsonBuilder().create();
String jse = gson.toJson(cars);
При попытке проделать эту операцию со списком (List в Json)
List<Car> cars = carSrv.getAll();
Gson gson = new GsonBuilder().create();
String jse = gson.toJson(cars);
Вылетает екзепшн:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:76)
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:69)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ArrayTypeAdapter.write(ArrayTypeAdapter.java:93)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson.toJson(Gson.java:661)
at com.google.gson.Gson.toJson(Gson.java:640)
at com.google.gson.Gson.toJson(Gson.java:595)
at com.google.gson.Gson.toJson(Gson.java:575)
...
Использую Gson библиотеку:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
Гдето в сети нашел решение с указанием типа:
List<Car> cars = carSrv.getAll();
Gson gson = new GsonBuilder().create();
Type listType = new TypeToken<List<Car>>() {}.getType();
String jse = gson.toJson(cars, listType);
НЕ ПОМОГЛО! тот же самій екзепшн
Нашел еще решение здесь и много его дублей :) Все же предполагаю, что проблема здесь не с хибернейтом, а с сериализацией
List<Car> cars = carSrv.getAll();
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY)
.create();
String jse = gson.toJson(cars);
класс HibernateProxyTypeAdapter взял из примеров.
public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null);
}
};
private final Gson context;
private HibernateProxyTypeAdapter(Gson context) {
this.context = context;
}
@Override
public HibernateProxy read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Not supported");
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void write(JsonWriter out, HibernateProxy value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
// Retrieve the original (not proxy) class
Class<?> baseType = Hibernate.getClass(value);
// Get the TypeAdapter of the original class, to delegate the serialization
TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));
// Get a filled instance of the original class
Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()
.getImplementation();
// Serialize the value
delegate.write(out, unproxiedValue);
}
}
НЕ ПОМОГЛО! екзепшн вида:
2018-мая-04 16:33:00.829 ERROR [http-nio-8080-exec-8] o.s.b.w.s.ErrorPageFilter - Forwarding to error page from request [/aes/by/id] due to exception [null]
java.lang.StackOverflowError: null
at com.google.gson.internal.bind.TypeAdapters$11.write(TypeAdapters.java:317)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at ua.avk.carwash.adapter.HibernateProxyTypeAdapter.write(HibernateProxyTypeAdapter.java:54)
at ua.avk.carwash.adapter.HibernateProxyTypeAdapter.write(HibernateProxyTypeAdapter.java:19)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968)
Вот сам класс Car, на всякий случай:
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity
@Table(name = "Car")
public class Car implements Serializable, Storable {
private static final long serialVersionUID = 1000000000000111L;
public static final String GET_BY_NAME = "select e from Car e where e.name = ?1";
public static final String GET_BY_TYPE = "select e from Car e where e.carType = ?1";
public static final String GET_BY_NUMBER = "select e from Car e where e.number = ?1";
public static final String GET_BY_CLIENT = "select e from Car e where e.client = ?1";
private Long id;
private String name;
private String number;
private CarType carType;
private Client client;
private List<Order> orderList = new ArrayList<>();
@JsonView(Views.User.class)
@JsonProperty("id")
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column(name = "car_id", nullable = false)
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@JsonProperty("name")
@JsonView(Views.User.class)
@Size(max = 50, message = "{size.field}")
@Column(name = "name", nullable = true, insertable = true, updatable = true, length = 50)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonProperty("number")
@JsonView(Views.User.class)
@Size(max = 8, message = "The car number must be {min} to {max} characters in length.")
@Column(name = "number", nullable = true, insertable = true, updatable = true, length = 8)
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@JsonProperty("cartype")
@JsonView(Views.User.class)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "type_id", nullable = true, insertable = true, updatable = true)
public CarType getCarType() {
return carType;
}
public void setCarType(CarType carType) {
this.carType = carType;
}
@JsonProperty("client")
@JsonView(Views.User.class)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "client_id", nullable = true, insertable = true, updatable = true)
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
//@Transient
@JsonProperty("orders")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonView(Views.Admin.class)
@OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
//@Column(name = "order_id")
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
@Override
public String toString() {
return String.format("%d, %s, %s, %s, %s;", id, name, number, carType, client);
}
/**
* The method Copy the object of the car
*
* @param u - the object of the car
*/
public void copy(Car u) {
this.setClient(u.getClient());
this.setOrderList(u.getOrderList());
this.setName(u.getName());
this.setNumber(u.getNumber());
this.setCarType(u.getCarType());
}
/**
* Override hashCode for correct work equals
*
* @return hashCode
*/
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(this.client)
.append(this.name)
.append(this.number)
.append(this.carType)
.toHashCode();
}
/**
* Compares of the car
*
* @param obj for compare
* @return true if equals
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Car))
return false;
if (obj == this)
return true;
Car u = (Car) obj;
return new EqualsBuilder()
.append(this.client, u.client)
.append(this.name, u.name)
.append(this.number, u.number)
.append(this.carType, u.carType)
.isEquals();
}
}
ВОПРОС: Как конвертировать List to Json в данной ситуации
Как я понял библиотеке Gson
тоже не понравились двунаправленные связи в сущностях. В борьбе с двух-направленными связями в сущностях или вот с этими екзепшинами:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
и возможным:
Infinity Exception
Который, кстати говоря, более понятно выражает суть проблемы!
Мне помогло:
Замена библиотеки Gson
на Jackson
, а именно:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
Использование аннотаций @JsonIgnore
или пару @JsonBackReference
и @JsonManagedReference
, о них можно прочесть здесь, здесь
@JsonManagedReference
обычная сериализация:@JsonIgnore
, @JsonBackReference
исключение из сериализации;Я применял вот так:
Класс Car
@Entity
@Table(name = "Car")
public class Car implements Serializable, Storable {
private static final long serialVersionUID = 1000000000000111L;
public static final String GET_BY_NAME = "select e from Car e where e.name = ?1";
public static final String GET_BY_TYPE = "select e from Car e where e.carType = ?1";
public static final String GET_BY_NUMBER = "select e from Car e where e.number = ?1";
public static final String GET_BY_CLIENT = "select e from Car e where e.client = ?1";
private Long id;
private String name="";
private String number="";
private CarType carType = new CarType();
private Client client = new Client();
private List<Order> orderList = new ArrayList<>();
@JsonProperty("id")
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column(name = "car_id", nullable = false)
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@JsonProperty("name")
@Size(max = 50, message = "{size.field}")
@Column(name = "name", nullable = true, insertable = true, updatable = true, length = 50)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonProperty("number")
@Size(max = 8, message = "The car number must be {min} to {max} characters in length.")
@Column(name = "number", nullable = true, insertable = true, updatable = true, length = 8)
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@JsonProperty("cartype")
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "type_id", nullable = true, insertable = true, updatable = true)
public CarType getCarType() {
return carType;
}
public void setCarType(CarType carType) {
this.carType = carType;
}
@JsonProperty("client")
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "client_id", nullable = true, insertable = true, updatable = true)
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
@JsonProperty("orders")
@JsonManagedReference
//@Transient
@OneToMany(fetch = FetchType.EAGER, mappedBy = "car")
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
@Override
public String toString() {
return String.format("%d, %s, %s, %d, %d, %s", id, name, number, carType.getId(), client.getId(), orderList);
}
/**
* The method Copy the object of the car
*
* @param u - the object of the car
*/
public void copy(Car u) {
this.setClient(u.getClient());
this.setOrderList(u.getOrderList());
this.setName(u.getName());
this.setNumber(u.getNumber());
this.setCarType(u.getCarType());
}
/**
* Override hashCode for correct work equals
*
* @return hashCode
*/
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(this.client)
.append(this.name)
.append(this.number)
.append(this.carType)
.toHashCode();
}
/**
* Compares of the car
*
* @param obj for compare
* @return true if equals
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Car))
return false;
if (obj == this)
return true;
Car u = (Car) obj;
return new EqualsBuilder()
.append(this.client, u.client)
.append(this.name, u.name)
.append(this.number, u.number)
.append(this.carType, u.carType)
.isEquals();
}
}
Класс CarType
@Entity
@Table(name = "CarType")
public class CarType implements Serializable, Storable {
private static final long serialVersionUID = 1000000000000112L;
public static final String GET_BY_TYPE = "select e from CarType e where e.type = ?1";
private Long id;
private String type;
private List<Car> carList = new ArrayList<>();
private List<Price> prices = new ArrayList<>();
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column(name = "car_type_id", nullable = false)
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@JsonProperty("type")
@Size(max = 15, message = "{size.field}")
@Column(name = "type", nullable = true, insertable = true, updatable = true, length = 15)
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@JsonProperty("cars")
@JsonManagedReference
//@Transient
@OneToMany(mappedBy = "carType")
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> carList) {
this.carList = carList;
}
@JsonProperty("prices")
@JsonManagedReference
//@Transient
@OneToMany(mappedBy = "type")
public List<Price> getPrices() {
return prices;
}
public void setPrices(List<Price> prices) {
this.prices = prices;
}
@Override
public String toString() {
return String.format("%d, %s, %s, %s", id, type, carList, prices);
}
/**
* The method Copy the object of the carList type
*
* @param u - the object of the carList type
*/
public void copy(CarType u) {
this.setCarList(u.getCarList());
this.setPrices(u.getPrices());
this.setType(u.getType());
}
/**
* Override hashCode for correct work equals
*
* @return hashCode
*/
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(this.carList)
.append(this.prices)
.append(this.type)
.toHashCode();
}
/**
* Compares of the carList type
*
* @param obj for compare
* @return true if equals
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CarType))
return false;
if (obj == this)
return true;
CarType u = (CarType) obj;
return new EqualsBuilder()
.append(this.carList, u.carList)
.append(this.prices, u.prices)
.append(this.type, u.type)
.isEquals();
}
}
Мне помогло - надеюсь поможет и Вам.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Теорема: Бинарное дерево можно однозначно восстановить имея InOrder и PostOrder/PreOrder последовательности, если последовательности не содержат дубликатов
Начал изучать Selenium WebDriverНад одной проблемой уже два дня голову ломаю
У меня есть программа , в которой есть своя встроенная (Embedded H2) databaseЯ могу подключиться к ее консоли находясь непосредственно в самой программе