Applications personalisation as exemplified by CRM: How does the use of JPA and specification helps managing investments and contractors

In an era of digital transformation, web and mobile applications have to be more and more advanced and flexible, in order to meet the growing demands of the market. As a Software House which specialises in creating bespoke solutions, we have experienced that efficiency in managing relations with clients, investments and contractors is key. In this article, I will discuss how Java Persistence API (JPA) technology, with its specification mechanism, helps us achieve this goal.

Advanced queries and filters:

In our case, one of the main uses of specifications in JPA is the ability to create advanced investment and contractor filters. With specifications, we can easily filter data by various fields such as the start and end date of the investment, investment type, region, city, etc..

Code example:

Below is an exemplary piece of the code that shows how we use the specification to filter investments:

@Cacheable(cacheNames = "Search_investments")
public Page<InvestmentListDTO> searchInvestments(Pageable pageable, String search) {
 SpecificationBuilder builder = SpecificationBuilder.parseString(
"investmentType=MAIN_INVESTMENT&"+search, Investment.specificationFields());
 try {
  Specification spec = -> new
   GenericSpecificationInvestment<>(criteria, new
  public Path apply(Root root, SearchCriteria criteria) {
  if (criteria.getKey().equalsIgnoreCase("investmentType")) {
   return root.get("investmentType");
  } else if (criteria.getKey().equalsIgnoreCase("city")) {
   return root.get("city");
  } else if (criteria.getKey().equalsIgnoreCase("province")) {
   return root.join("regions").get("name");
  } else if (criteria.getKey().equalsIgnoreCase("coordinator")) {
   return root.join("coordinator").get("name");
  } else if (criteria.getKey().equalsIgnoreCase("contractor")) {
   return root.join("contractors").get("name");
  } else if (criteria.getKey().equalsIgnoreCase("contractorType")) {
   return root.join("contractors").get("type");
  } else if (criteria.getKey().equalsIgnoreCase("startDate")) {
   return root.join("calendar").get("startDate");
  } else if (criteria.getKey().equalsIgnoreCase("status")) {
   return root.join("calendar").get("status");
  } else if (criteria.getKey().equalsIgnoreCase("endDate")) {
   return root.join("calendar").get("endDate");
  } else {
   return root.get(criteria.getKey());

return investmentRepository.findAll(spec,pageable)
} catch (NullPointerException e){
 throw new SearchException(search);

In this case, we use a dynamically built query to find investments that meet specific criteria. With this mechanism, we can easily customize queries to the individual customer’s needs.

Usage in CRM:

Dynamicity and flexibility that JPA offers, are extremely useful in following aspects:

Segmentation of investments and contractors:

By using specifications, we can segment investments and contractors according to different criteria. This enables more precise project management and better use of resources.

Reporting and analysis:

Advanced queries give us the ability to create deep analyses and reports, which are essential for effective management.

Automation and efficiency:

Flexibility in queries and the ability to create them dynamically allow us to automate many processes, which significantly increases the efficiency of the system.

The use of JPA technology and its specification mechanism in investment and contractor management in CRM systems can greatly increase efficiency and precision. This is crucial for companies such as Ultimate Systems that want to deliver the most advanced and personalized application products to their customers.