Issue
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?
Solution
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()
Answered By - Ken Chan
Answer Checked By - Mary Flores (JavaFixing Volunteer)