Hello everyone,
Greetings today!
Today we'll explore NamedQuery with JPA and Hibernate, so let's get started.
What is NamedQuery: NamedQuery is a way through which we can define a query over an entity class with some name assigned to it which can be used in the repository layer to refer to a query, so instead of writing queries in the repository layer we can group queries in entity class which makes our repository layer code more readable and maintainable.
Note-NamedQuery is compiled and validated on application start-up which makes our application fail fast when there is an error in the query.
Disadvantages of NamedQuery: Named queries cannot be customized at runtime, but you can pass parameters to NamedQuery at runtime.
Defining NamedQuery
We can define NamedQuery over entity class using @javax.persistence.NamedQuery annotation, we need to specify 2 properties name and query, let's see with an example.
@NamedQuery(name = "findByRollNo",query = "Select s from Student s")
We can pass parameters at runtime as shown below using:parameterName
@Entity @NamedQuery(name = "findByRollNo", query = "Select s from Student s where rollNo=:rollNo") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer rollNo; private String name; private String standard; private String address; private String emailId; }
We need to set the parameterName value at runtime in the above example we need to set the value of rollNo.
Calling NamedQuery Using JPA
For this, we need to use EntityManager's createNamedQuery method as shown below
TypedQuery<Student> typedQuery=entityManager.createNamedQuery("findByRollNo", Student.class);
We can set parameter values using setParameter on the typed query.
typedQuery.setParameter("rollNo",rollNo);
@Repository @Transactional public class StudentRepository { @Autowired private EntityManager entityManager; @Autowired private SessionFactory sessionFactory; public Optional<Student> findByRollNo(Integer rollNo){ TypedQuery<Student> typedQuery=entityManager .createNamedQuery("findByRollNo", Student.class); typedQuery.setParameter("rollNo",rollNo); return typedQuery.getResultStream().findFirst(); }
Calling NamedQuery With Hibernate
With hibernate, we need to use a session object instead of an entity manager to refer to the named query we defined in the entity class as shown below.
@Repository @Transactional public class StudentRepository { @Autowired private SessionFactory sessionFactory; public Optional<Student> findByEmailId(String emailId){ Session session = sessionFactory.openSession(); Query<Student> query = session .createNamedQuery("findByEmailId", Student.class); query.setParameter("emailId",emailId); return query.getResultStream().findFirst(); }
We can combine multiple NamedQuery under 1 annotation over entity class to make code more readable using @NamedQueries of javax.persistence as shown below
@NamedQueries({
@NamedQuery(name = "findByRollNo",query = "Select s from Student s where rollNo=:rollNo"),
@NamedQuery(name = "findByEmailId",query = "Select s from Student s where emailId=:emailId")
})
@Repository @Transactional public class StudentRepository { @Autowired private EntityManager entityManager; public OptionalfindByName(String name){ TypedQuery typedQuery=entityManager .createNamedQuery("findByName", Student.class); typedQuery.setParameter("name",name); return typedQuery.getResultStream().findFirst(); }
0 Comments
If you have any doubts let me know.