Hibernate создаёт лишнюю таблицу для связи многие ко многим, хотя такой связи у меня нет
У меня есть таблица Car там данные некоторой машины, эта таблица связана связью OneToOne с таблицей Description, в которой содержится больше информации о машине. Таблица Description связана OneToMany с таблицей Image в которой находятся фотографии этой машины.
Соответственно класс Car
@Entity
@Table
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String markName;
@Column
private String modelName;
@Column
private String issueYear;
@Column
private Double price;
@Column
private String type;
@Column
private String frontPicture;
@OneToOne(fetch = FetchType.LAZY)
private Description description;
}
класс Description
@Entity
@Table
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Description {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String transmission;
@Column
private String description;
@Column
private String colour;
/*@JsonIgnore
@OneToOne(fetch = FetchType.LAZY)
private Car car;*/
@OneToMany(fetch = FetchType.LAZY)
private Collection<Image> image;
}
класс Image
@Entity
@Table
@Data
@NoArgsConstructor
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String pictureURL;
/* @JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
private Description description;*/
}
Проблема: когда я работаю с этим в контроллере(просто получаю таблицу Car) выбрасывает ошибку
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->by.grsu.vitovt.carsharing.model.entity.Car["description"]->by.grsu.vitovt.carsharing.model.entity.Description$HibernateProxy$mN4rMr1z["hibernateLazyInitializer"])
а также hibernate создает таблицу DESCRIPTION_IMAGE(Description_id,image_id) хотя связь manyToMany я не делал. P.S. я думал что проблема в том что json зацикливался и комментировал эти места в классах, но даже после этого проблемы не ушли.
Ответы (1 шт):
Ошибка возникает ввиду этого:
...
@OneToOne(fetch = FetchType.LAZY)
private Description description;
...
@OneToMany(fetch = FetchType.LAZY)
private Collection<Image> image;
...
FetchType.LAZY
Вклчючение SerializationFeature.FAIL_ON_EMPTY_BEANS, как предлагается в сообщении об ошибке, не приведет к желаемому результату и только спрячет ошибку.
Поля, помеченные FetchType.LAZY, загружаются из БД по требованию при первом обращении. В момент загрузки родительской сущности Hibernate кладет в такие поля Proxy-объект, который и подгружает данные из базы. Проблема в том, что здесь сериализация осуществляется до загрузки данных. Попробуйте подгрузить данные перед сериализацией, например, обратившись к полям "вручную", или указав FetchType.EAGER
Важный момент, данные могут быть подгружены только в рамках той сессии, в которой была создана родительская сущность. Контролировать время жизни сессии можно разными способами, например с помощью @Transactional. При поытке загрузки коллекции вне сессии, в рамках которой получен объект, будет возникать ошибка LazyInitializationException
Создание третьей таблицы - это нормальное поведение в данном случае:
When using a unidirectional @OneToMany association, Hibernate resorts to using a link table between the two joining entities.