Guide to EzyDatabaseRepository, EzyJpaRepository, and Transactions
Updated at 1782264852000In most cases, users should define repositories by extending
EzyDatabaseRepository. This is the default and recommended approach for common CRUD operations, method-name queries, @EzyQuery, pagination, count, delete, and simple update operations.@EzyRepository public interface UserRepository extends EzyDatabaseRepository<Long, User> { User findByEmail(String email); List<User> findByStatus(String status, EzyNext next); long countByStatus(String status); int deleteByStatus(String status); @EzyQuery("update User e set e.status = ?1 where e.id = ?0") int updateStatus(long id, String status); }
With this approach, EzyData automatically generates the repository implementation. Methods such as
findBy..., countBy..., deleteBy..., or methods annotated with @EzyQuery are converted into corresponding JPA queries.When to Use EzyDatabaseRepository
Use
EzyDatabaseRepository when:- the repository only needs common CRUD operations,
- the query can be expressed by method name, such as
findByEmail,countByStatus, ordeleteById, - the query can be written directly with
@EzyQuery, - one transaction per write query is enough,
- you do not need to control
EntityManagermanually, - you do not need to group multiple JPA operations into one manual transaction.
This should be the preferred approach because the code is shorter, easier to read, and consistent with EzyData’s auto-implementation mechanism.
Default Transaction Behavior
When using an auto-implemented repository from
EzyDatabaseRepository, EzyData handles transactions for write queries.Methods starting with
update... and delete... are executed inside a transaction:@EzyQuery("update User e set e.status = ?1 where e.id = ?0") int updateStatus(long id, String status); int deleteByEmail(String email);
Internally, the flow is:
transaction.begin(); try { query.executeUpdate(); transaction.commit(); } catch (Exception e) { transaction.rollback(); throw e; }
Read methods such as
findBy..., countBy..., and fetch... only create a query, fetch data, and close the EntityManager; they do not start a write transaction.When to Use EzyJpaRepository
In some cases, users may want to implement transactions themselves or control the
EntityManager directly. In that case, create a repository class and extend EzyJpaRepository.This approach is suitable when:
- you need to group multiple JPA operations into the same transaction,
- you need to execute multiple queries before committing,
- you need to decide when to
flush,commit, orrollback, - you need to use specific
EntityManagerAPIs, - the business logic is too complex for
@EzyQuery, - the transaction must wrap multiple business steps inside one repository method.
Example:
@EzyRepository public class UserRepository extends EzyJpaRepository<Long, User> { public void changeEmailAndStatus( long userId, String email, String status ) { EntityManager entityManager = databaseContext.createEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); try { transaction.begin(); User user = entityManager.find(User.class, userId); user.setEmail(email); user.setStatus(status); entityManager.merge(user); transaction.commit(); } catch (Exception e) { transaction.rollback(); throw e; } finally { entityManager.close(); } } }
Then register the repository class:
EzyDatabaseContext context = new EzyJpaDatabaseContextBuilder()
.entityManagerFactory(entityManagerFactory)
.repositoryClass(UserRepository.class)
.build();
Recommendation
By default, use
EzyDatabaseRepository so EzyData can automatically generate the repository implementation and handle transactions for each write query.Only use
EzyJpaRepository when you truly need to manage transactions yourself or work directly with EntityManager. It gives you more flexibility, but you are responsible for calling begin, commit, rollback, and close correctly.