Reputation: 65
I'm trying to create a one-to-one relationship. On the owner side, the bookIsn
(non-primary) is referring to the primary key of the target entity.
Now the issue is if I want to read all reviews (reviewRepository.findAll()
) the following error is thrown if no book is available for the given bookIsn
:
Unable to find com.repository.model.Book with id 1
But the expecting behavior would be that the book entity simply is set to null
if no book could be found. Like it does if I use the reviewId
for joining the column @JoinColumn( name = "review_id", ... )
instead of the review_isn
.
Can somebody explain why it's working with a primary key, but not for a non-primary attribute? What needs to be done to make it work for non-primary attributes as well?
Below the two classes:
Review.java:
@Entity
@Data
@Table(name = "review")
public class Review {
@Id
@Column(name="review_id")
private String reviewId;
@Column(name="book_isn")
private String bookIsn;
@OneToOne
@JoinColumn(
name = "book_isn",
referencedColumn = "book_isn",
insertable = false,
updatable = false)
private Book book;
}
Book.java:
@Entity
@Data
@Table(name = "book")
public class Book {
@Id
@Column(name="book_isn")
private String bookId;
@Column(name="book_name")
private String bookName;
}
Upvotes: 1
Views: 633
Reputation: 13041
First of all I have to say that I would not suggest you to use @Data
lombok annotation with hibernate entity class. See for example this article.
Then, I would suggest you to correct your Review
entity mapping in this way:
import javax.persistence.Transient;
@Entity
@Table(name = "review")
public class Review
{
private String reviewId;
private Book book;
@Id
@Column(name = "review_id")
public String getReviewId()
{
return reviewId;
}
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "book_isn")
public Book getBook()
{
return book;
}
// setters omitted for brevity
@Transient
public String getBookId()
{
return book != null ? book.getBookId() : null;
}
}
You can persist your Review
entities in the following way:
Book b1 = new Book();
b1.setBookId("BK1");
b1.setBookName("Book 1");
Review r1 = new Review();
r1.setReviewId("R1");
r1.setBook(b1);
session.persist(r1);
Review r2 = new Review();
r2.setReviewId("R2");
session.persist(r2); // book_isn is NULL for the R2 Review
P.S. Please also note that it is not recommended to use string as a type for primary key for big tables due to the potential performance problem.
Upvotes: 1