Home > other >  MappingException Repeated column in mapping for entity: models.Book column: author_id (should be map
MappingException Repeated column in mapping for entity: models.Book column: author_id (should be map

Time:04-23

i always got an exception, when trying to

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

Author class:

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

Book class:

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

I was trying without private long author_id but then i cannot set author id How can i solve it?

CodePudding user response:

It is because you map author_id column to the multiple non read-only fields (author_id and author) in Book. It is not allowed because if they have different values , Hibernate does not know which value should it use for author_id column when updating/inserting its value.

So either remove one of them or configure one of them as read-only :

To configure author_id to be read-only , you can do :

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

To configure Author to be read-only , you can do :

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

The better solution is just make sure only one field is mapped to author_id , so I would remove author_id field.

To configure the Author for a book , it is better that you first query the Author first from the DB . It can also help to validate if an Author with a given Id really exist or not. Otherwise if there are no author with that ID , it will violate its FK constraint when saving the Book. As you you already got the Author instance , you can simply use it to configure the new book 's Author.

If you really want to save one DB call to get the author , you can consider to use EntityManager 's getReference() to get a Author proxy such that you can use it to configure the new book 's Author :

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

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

Also see this for the more details about the behaviour of getReference()

  • Related