JPA Find Entity Example

Lokesh Gupta

In JPA, once an entity is persisted in the database, the next thing we typically want to do is find it again. Let’s see how an entity can be found using the EntityManager, JPQL, and other similar methods.

1. Find Entity using EntityManager.find()

The find() method retrieves an entity by its primary key. It returns null if the entity is not found. The find() method performs a synchronous fetch i.e. when we call this method, it immediately attempts to retrieve the entity from the database or the persistence context.

The entity returned by find() is always in the managed state. All changes to this entity within the transaction are tracked and persisted in the database when the transaction is committed.

In the following example, we are fetching the DepartmentEntity with the primary key as ‘123‘.

//Injected with DI 
private EntityManagerFactory emf;

public DepartmentEntity findDepartmentById(Long id) {

  EntityManager em = emf.createEntityManager();
  try {
    DepartmentEntity dept = em.find(DepartmentEntity.class, id);
    return dept;
  } finally {
    em.close();
  }
}

This is all the information needed by the entity manager to find the instance in the database. When the call completes, the department that gets returned will be a managed entity, meaning that it will exist in the current persistence context associated with the entity manager. Passing in the class as a parameter also allows the find() method to be parameterized and return an object of the same type that was passed in, saving the caller an extra cast.

What happens if the object has been deleted or you supply the wrong ID by accident? If the entity is not found, then the find() call simply returns null. You would need to ensure that a null check is performed before the next time the department variable is used.

2. Find Multiple Entities using JPQL

Let’s say you want to find all the departments matching a specified name then the find() method will not be able to get you the desired result because it can find only one department entity at a time. To get multiple departments in the result, we can use JPQL in the below manner.

public List<DepartmentEntity> getDepartmentsByName(String name) {

  String jpql = "SELECT d FROM Department d WHERE d.name = :name";
  TypedQuery<DepartmentEntity> query = em.createQuery(jpql, DepartmentEntity.class);
  query.setParameter("name", name);

  List<DepartmentEntity> depts = query.getResultList();
  return depts;
}

The above query can be modified to return the list of departments based on other criteria as well, which you can specify using the WHERE clause.

3. Find Entities with Named Queries

The named queries are pretty much similar to JPQL queries except they are defined in a common place using annotations, and later referred with the given name to the query.

For example, we have defined the ‘Department.findByName‘ named query in the DepartmentEntity.java class using the @NamedQuery annotation.

@Entity
@NamedQuery(name = "Department.findByName", query = "SELECT d FROM Department d WHERE d.name = :name")
public class DepartmentEntity {

    @Id
    private Long id;
    private String name;

    // Constructors, getters, setters, etc.
}

Later, we can refer to this query by its name and execute it similar to JPQL.

public List<DepartmentEntity> getDepartmentsByName(String name) {

  TypedQuery<Person> query = em.createNamedQuery("Person.findByName", Person.class);
  query.setParameter("name", name);

  List<DepartmentEntity> depts = query.getResultList();
  return depts;
}

4. Find Entities using Criteria API

As we define the static text queries in JPQL and named queries, we can build similar queries dynamically using the CriteriaBuilder API. This is particularly useful for complex queries.

public List<DepartmentEntity> getDepartmentsByName(String name) {

  EntityManager em = emf.createEntityManager();

  try {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<DepartmentEntity> cq = cb.createQuery(DepartmentEntity.class);
    Root<DepartmentEntity> dept = cq.from(DepartmentEntity.class);
    cq.select(dept).where(cb.equal(dept.get("name"), name));
    return em.createQuery(cq).getResultList();
  } finally {
    em.close();
  }
}

5. Find Entities using Spring Data JPA Repository

When using Spring Data Repository interfaces, the best way to find entities is using the custom repository methods, These methods automatically generate the required queries based on method names or annotations.

public interface DepartmentRepository extends JpaRepository<DepartmentEntity, Long> {

    List<Person> findByName(String name);
}

Next, we can use the findByName() in a service class as follows:

@Service
public class DepartmentService {

    @Autowired
    private DepartmentRepository departmentRepository;

    public List<Person> findDepartmentsByName(String name) {
        return departmentRepository.findByName(name);
    }
}

6. Summary

In this tutorial, we discussed different methods to find JPA entities on various conditions. Let’s recap these methods:

  • EntityManager.find() is the simplest and most direct method to retrieve an entity by its primary key.
  • JPQL Query enables flexible querying using JPQL for complex conditions.
  • Named Queries help in creating predefined queries for reuse and better code organization.
  • Criteria API is best for type-safe and dynamic query construction.
  • Spring Data repository methods are specific to the Spring framework which simplifies data access with automatically generated query methods.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.