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 шт):

Автор решения: tequillaz

Ошибка возникает ввиду этого:

...
    @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.

→ Ссылка