MappingException Повторяющийся столбец в сопоставлении для объекта: models.Book столбец: author_id (должен быть сопоставлен с помощью insert="false" update="false")

я всегда получаю исключение, когда пытаюсь

Book book = new Book(); 
book.setAuthor_id(4);
book.setTitle("test");

Авторский класс:

public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @Column(name = "name")
    private String name;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "author")
    private Set<Book> books;
    // getters and setters

Книжный класс:

public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @Column(name = "title")
    private String title;

    @Column(name = "author_id")
    private long author_id;

    @ManyToOne(optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "author_id")
    private Author author;
    //getters and setters

Я пытался без private long author_id, но тогда я не могу установить идентификатор автора Как я могу это решить?

Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
0
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это потому, что вы сопоставляете столбец author_id с несколькими полями, не предназначенными только для чтения (author_id и author) в Book. Это не разрешено, потому что, если они имеют разные значения, Hibernate не знает, какое значение следует использовать для столбца author_id при обновлении/вставке его значения.

Поэтому либо удалите один из них, либо настройте один из них как доступный только для чтения:

Чтобы настроить author_id только для чтения, вы можете сделать:

@Column(name = "author_id" , insertable=false, updatable=false)
private long author_id;

Чтобы настроить Author только для чтения, вы можете сделать:

@ManyToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "author_id", insertable=false, updatable=false)
private Author author;

Лучшее решение — просто убедиться, что только одно поле сопоставлено с author_id, поэтому я бы удалил поле author_id.

Чтобы настроить автора для книги, лучше сначала запросить автора из базы данных. Это также может помочь проверить, действительно ли существует автор с данным идентификатором или нет. В противном случае, если нет автора с таким идентификатором, это нарушит ограничение FK при сохранении книги. Поскольку у вас уже есть экземпляр Author, вы можете просто использовать его для настройки Author новой книги.

Если вы действительно хотите сохранить один вызов БД, чтобы получить автора, вы можете рассмотреть возможность использования EntityManager's getReference() для получения прокси-сервера автора, чтобы вы могли использовать его для настройки автора новой книги:

Author author = entityManager.getReference(Author.class , 4);

Book book = new Book(); 
book.setAuthor(author);
book.setTitle("test");

Также см. это для более подробной информации о поведении getReference()

Другие вопросы по теме