EzyJPA Introduction

1. Introduce EzyJPA

EzyJPA (Easy going to JPA Interaction) is a framework support to interact to JPA, It supports:
  1. Transparently map your Java entities to database record and back
  2. Query, update, delete and aggregation by query string
  3. Annotation driven

2. Structure of EzyJPA

  1. Database Context: wraps EntityManager, DataBinding. Manages repositiors, QueryManager and DataSerializers. Provides function to get repostiories, queries and serializers
  2. Repostiories: Manages all repostiores by name and type
  3. QueryManager: Manages all queries, collects queries from annotations and deverloper set
  4. DataSerializers: Manages all data serializers and deserializers, provide a way to allow deverloper custom and set their serializers and deverlopers
  5. Repostiory: converts queries, data and calls to database

3. Install JPA

1. To use EzyJPA you need add dependency
The latest version can be found in the Maven Central repository.
2. To use EzyJPA you need configure to create repositories
You can use ezyfox-boot-autoconfigure by add to your pom.xml:
Or because with some reason, you can not use ezyfox-boot-autoconfigure you can config like this:
import com.tvd12.ezydata.database.EzyDatabaseContext;
import com.tvd12.ezydata.jpa.EzyJpaDatabaseContextBuilder;
import com.tvd12.ezydata.jpa.loader.EzyJpaDataSourceLoader;
import com.tvd12.ezydata.jpa.loader.EzyJpaEntityManagerFactoryLoader;
import com.tvd12.ezyfox.bean.EzyBeanConfig;
import com.tvd12.ezyfox.bean.EzyPackagesToScanAware;
import com.tvd12.ezyfox.bean.EzySingletonFactory;
import com.tvd12.ezyfox.bean.EzySingletonFactoryAware;
import com.tvd12.ezyfox.bean.annotation.EzyAutoBind;
import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.util.EzyPropertiesAware;
import lombok.Setter;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
import java.util.Set;

import static com.tvd12.ezyfox.boot.util.EzyDatabaseContexts.addRepositoriesFromDatabaseContextToSingletonFactory;

public class EzyJpaConfiguration implements
    EzySingletonFactoryAware {

    private Properties properties;
    private EzySingletonFactory singletonFactory;

    public void config() {

    private EzyDatabaseContext databaseContext() {
        return new EzyJpaDatabaseContextBuilder()

    private EntityManagerFactory entityManagerFactory() {
        return new EzyJpaEntityManagerFactoryLoader()

    private DataSource dataSource() {
        return new EzyJpaDataSourceLoader()
            .properties(properties, "datasource")
3. You can add to your configuration file like this:
# for application.yaml
  jdbcUrl: jdbc:mysql://root:12345678@localhost:3306/test
  driverClassName: com.mysql.cj.jdbc.Driver
# for application.properties

4. Example

For full example you can look at ezyfox-examples Github repo
Let’s say we need create an http server application to manage a book store (Category, Author and Book), we need 6 apis
  • api/v1/author/add: Add an author
  • api/v1/category/add: Add a category
  • api/v1/book/add: Add a book
  • api/v1/books/{bookId}: Get a book by id
  • api/v1/books: Get a list of books
  • apiv1/books/expected-revenue:
4.1 Create entities class
To store Category, Author and Book to MySQL, we need create 3 entities
@EqualsAndHashCode(of = "id", callSuper = false)
public class Author extends CommonEntity {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String name;

@EqualsAndHashCode(of = "id", callSuper = false)
public class Book extends CommonEntity {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long categoryId;
    private Long authorId;
    private String name;
    private BigDecimal price;
    private LocalDate releaseDate;
    private LocalDateTime releaseTime;

@EqualsAndHashCode(of = "id", callSuper = false)
public class Category extends CommonEntity {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String name;
4.2 Create repositories
We need create 3 repositories for 3 entities
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Author;
import com.tvd12.ezyfox.database.annotation.EzyRepository;

public interface AuthorRepository extends EzyDatabaseRepository<Long, Author> {
import java.util.List;

import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Book;
import com.tvd12.ezydata.example.jpa.result.SumBookPriceResult;
import com.tvd12.ezyfox.database.annotation.EzyQuery;
import com.tvd12.ezyfox.database.annotation.EzyRepository;
import com.tvd12.ezyfox.util.Next;

public interface BookRepository extends EzyDatabaseRepository<Long, Book> {

    Book findByNameAndAuthorId(String name, Long authorId);

    @EzyQuery("select e from Book e")
    List<Book> findBooks(Next next);

    @EzyQuery("select e from Book e where e.name < ?0 order by e.name")
    List<Book> findByNameLt(String name, Next next);

    @EzyQuery("select e from Book e where e.name > ?0 order by e.name")
    List<Book> findByNameGt(String name, Next next);

    @EzyQuery(value = "select sum(e.price) as sum from Book e", nativeQuery = true)
    SumBookPriceResult sumPrice();
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Category;
import com.tvd12.ezyfox.database.annotation.EzyRepository;

public interface CategoryRepository extends EzyDatabaseRepository<Long, Category> {
    Category findByName(String name);
4.3 Save entities
Save a category, see more details
final Category entity = dataToEntityConverter.toEntity(data);
Save an author, see more details
final Author entity = dataToEntityConverter.toEntity(data);
Save a book, see more details
final Book book = dataToEntityConverter.toEntity(data);
4.4 Query data
Find a category by id, see more details
Category category = categoryRepository.findById(request.getCategoryId());
Find an author by id, see more details
Author author = authorRepository.findById(request.getAuthorId());
Find a book by name and author id, see more details
Book existedBook = bookRepository.findByNameAndAuthorId(
Get sum of all book prices, see BookRepository and BookService to get more details
@EzyQuery(value = "select sum(e.price) as sum from Book e", nativeQuery = true)
SumBookPriceResult sumPrice();
Full source code available on Github

5. Conclusion

With EzyJPA you will work with database lot easier. With query string, you will don't need care about data and query result mapping, you will reduce a lot of your source code, save your time to focus to your business


You can take a look the list of default functions