My Case
I have two entities, student
and school
which are structured as follows:
@Table(name = "Student")
public class Student
{
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "school")
private School school
}
@Table(name = "School")
public class School
{
@Id
@Column(name = "id")
private String id;
@Column(name = "state")
private String state;
}
The following are the two views values:
Student
id | name | school |
---|---|---|
A | Albert | MCD |
B | Kevin | LSU |
C | Jack | NY |
D | Robert | CA |
School
id | name |
---|---|
MCD | Mich |
LSU | Los |
CA | Car |
So when in hibernate i'm doing a simple select * from Student
, it throws an error because the 'NY' id does not exist in the school table.
(To be precise, it throws org.hibernate.LazyInitializationException: No row with the given identifier exists
)
Final Goal
My goal is to bypass the error that is thrown an still return the correct entity (So Albert, Kevin, Robert)
CodePudding user response:
You need to add @NotFound(action = NotFoundAction.IGNORE)
on top of School in Student
class. As mentioned by Davide d'Alto on his answer, there's no NY
in table School
so an exception will be risen by default.
Fixing the database should be the proper answer but sometimes it's not possible or might have other undesired consequences on other applications.
In this case, when annotating with @NotFound(action = NotFoundAction.IGNORE)
the value will be set to null
in case it's not found.
@Table(name = "Student")
public class Student
{
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "school")
private School school
}
More info:
Baeldung - Hibernate EntityNotFoundException
CodePudding user response:
You said that you're using a simple SELECT * FROM Student
query, which means you are using custom queries.
In your case, you should be able to change it to SELECT * FROM Student St LEFT JOIN School Sc ON Sc.ID = St.School;
.
What that should do is load all of the records in one query and any student records that don't have a matching school should return null for the School
attribute on the Student
class.
Side Note: When working with relationships and JPA, if it's a simple relationship like this, you can use joins to ensure everything is loaded in one query, rather than JPA loading all of the parent entities and then issuing a query for each of those to fetch the child entities, so it can have quite the performance improvement.