Java JPA: Transaction logic in DAO vs Service

Being new to JPA and transaction management, I have a Spring Boot REST API application layered like this:

Controller -> Service -> DAO -> DB

I want to be agnostic from any ORM and am using only JPA annotations and concepts like Entity Manager, PersistenceContext etc.
Having a DAO layer, my question is where should I manage transaction logic: in DAO? In the Service layer?
For now my DAO is implementing standard CRUD logic like:

public void save(IEntityObject entity){
        entityManager.getTransaction().begin();
        entityManager.persist(entity);
        entityManager.getTransaction().commit();
        entityManager.close();
    }

//other CRUD methods

But this makes a lot of duplicate code! So is it a good idea to put the transaction management related logic in the service above in a generic method, but how? What about rollback logic?
Is there any standard pattern for this?
Thank you

New contributor

DAN is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Transactions are very dependent on the use case. While there is no standard architecture, putting transaction logic in the layer of the application that has the most knowledge about the use case will give you the fewest headaches.

The advantage of placing transaction logic in the DAO is that you hide these data access details from the rest of the application. The downside is that your DAO is not very knowledgeable about the use case, so it has a hard time understanding when to start, commit, or roll back transactions. The DAO should provide general purpose data access logic that could be reused in multiple use cases.

With a service layer, I expect controllers to handle the semantics of the HTTP request-response lifecycle along with knowing which use case should be invoked. That leaves the service layer to handle business logic, coordination logic, validation, and transaction management. The trick is to create an abstraction to hide the specifics of your ORM, yet still acknowledge that a transaction is necessary.

While the following seems more prevalent in C#, the Unit of Work design pattern might be a good fit.

A unit of work is a behavioral pattern in software development. Martin Fowler has defined it as everything one does during a business transaction which can affect the database. When the unit of work is finished, it will provide everything that needs to be done to change the database as a result of the work.

Source: Wikipedia

If you research the unit of work pattern, don’t get too hung up on the repository pattern. You will see a lot of references to that. Simply replace “repository” with “Data Access Object” and you should be fine. The important bits are:

  • Define an interface for a specific unit of work.
  • The interface should define methods to commit or roll back the transaction.
  • The interface should not require types from your data access layer, if you desire strict decoupling of those concerns.
  • Include all data access methods necessary to complete a particular use case.

Internally, the unit of work can reference any data access objects it needs. Don’t think of this as a one-to-one mapping of DAOs with additional “commit” and “rollback” methods. The DAOs are an implementation detail of the unit of work that doesn’t need to be exposed to the rest of the application. And don’t get too hung up on naming things, either. I’ve seen unit of work implementations that dance around “commit” and “rollback” using methods named like “saveChanges” or “discardChanges”. Relational databases don’t have ownership over simple and concise terms like commit and rollback. The main point is to decouple data access from use case logic, rather than pretending a database doesn’t exist.

1

Controller -> Service -> DAO -> DB

It depends on how responsibilities has been defined. If DAO per database table is used then a DAO (data access object) responsibility is to preserver data integrity of a database table – a common technique is locking, optimistic or pessimistic – that would make Service responsible to preserver business data model integrity – a common technique is transaction, that could involve other resources besides database.

  1. When you dive in depth, you will understand that transaction is not something you could wrap inside a simple save method.
  2. Transactions operate on service layer. Because there will be cases where you will need to save two or more Entities together to complete a transaction.
  3. Then there are distributed transactions where multiple databases need to co-ordinate to complete a transaction..

Spring itself has it’s own declarative transaction management. It is proven, comprehensive and used everyday in every enterprise applications.

Search for tutorials related to @transactional annotation. Or read Spring Documentation

Example:

Enable Spring Transaction Configuration in application

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
       //...
   }

   @Bean
   public PlatformTransactionManager transactionManager() {
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
      return transactionManager;
   }
}

Then wrap the service layer with a transactional annotation

@Service
@Transactional
public class FooService {
    //...
}

New contributor

Raja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật