Want to handle declarative transactions at the service layer

Asked 2 years ago, Updated 2 years ago, 138 views

//DAO
@Transactional
public class UserDAO implements UserDAO Interface {

    @ Inject
    EntityManagerem;

    public User find(intid){
        return em.find(User.class,id);
    }

    @ Override
    public void update (User user) {
        // TODO Auto-generated method stub
        em.merge(user);
        em.flush();
    }

    // Transaction processing is successful (rollback) here
    public void transaction (User buyer, Item item) {
        User seller=find(item.getSellerId());
        int price = item.getPrice();
        buyer.setBalance(buyer.getBalance()-price);
        update(buyer);
        if(true){
            through new RuntimeException();
        }
        seller.setBalance(seller.getBalance()+price);
        update(seller);
    }

}

If you call the DAO transaction method above, it will roll back normally.

// Service Layer (Business Logic)
@Transactional
public class UserLogic implements UserLogicInterface {

    UserDAOInterface dao=Guice.createInjector (new JpaPersistDaoModule())
            .getInstance(UserDAO.class);

    publicUser signIn(String email, String password) {
        return dao.find(email, password);
    }

    // This will not run (rollback) successfully
    public void transaction (User buyer, Item item) {
        User seller=dao.find(item.getSellerId());
        int price = item.getPrice();
        buyer.setBalance(buyer.getBalance()-price);
        dao.update(buyer);
        if(true){
            through new RuntimeException();
        }
        seller.setBalance(seller.getBalance()+price);
        dao.update(seller);
    }

}

Invoking this method did not work (copy and paste method).

The latter is what you want to do (or you have to do something disgusting to have EntityManager in your business logic and give it to DAO's method as an argument). Thank you.

This is a supplement.
I use Google Guice and PostgresSQL.

java-ee jpa

2022-09-30 19:54

1 Answers

The problem was with the following code.

// Service Layer (Business Logic)
@Transactional
public class UserLogic implements UserLogicInterface {

    UserDAOInterface dao=Guice.createInjector (new JpaPersistDaoModule())
            .getInstance(UserDAO.class);

    publicUser signIn(String email, String password) {
        return dao.find(email, password);
    }

    // This will not run (rollback) successfully
    public void transaction (User buyer, Item item) {
        User seller=dao.find(item.getSellerId());
        int price = item.getPrice();
        buyer.setBalance(buyer.getBalance()-price);
        dao.update(buyer);
        if(true){
            through new RuntimeException();
        }
        seller.setBalance(seller.getBalance()+price);
        dao.update(seller);
    }

}

This Code

UserDAOInterface dao=Guice.createInjector (new JpaPersistDaoModule())
            .getInstance(UserDAO.class);

Here's the part. Here's

@Inject
UserDAOInterface dao;

Rewrite
Furthermore, when generating this class,
new UserLogic();
Instead of
UserLogic=Guice.createInjector (new JpaPersistDaoModule()) .getInstance(UserLogic.class);
It seems that it was the right answer.

Sorry for the trouble.


2022-09-30 19:54

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.