-1

I have a scenario where i need to call some service in the DAO layer to fetch some data based on a input coming from the database(in the resultset). so what best to way to instantiate the service. Inject in the DAO constructor or instanstiate inside the result set. see the below example for lucid understanding

 public class ParticipationDao {

  private ConnectionFactory connectionFactory'
  private int userId;

    /**
     * Constructor which injects dependencies
     */
    public  ParticipationDao(String userId, ConnectionFactory connectionFactory) {
        this.userId = userId;
        this.connectionFactory = connectionFactory;

    }

    public List<Participation> getParticipantDetails(Integer studyId) throws StudyParticipationException {

        List<Participation> participationList = new ArrayList<>();
        String query = //some QUERY.....
        try (Connection connection = connectionFactory.getConnection();
                PreparedStatement stmt = connection.prepareStatement(query); ) {
            stmt.setInt(1, studyId);
            try (ResultSet rs = stmt.executeQuery();) { 
                while (rs.next() ) {
                    Participation p = new Participation();
                    //SOME OTHER ASSIGNMENTS ......
                    String modifiedUserId = rs.getString("ModifiedByID");
                    // TODO call some service here to get the username and assign to the setUserName method.
                    p.setUserName(assignHere);

                    participationList.add(p);
                } 
            }
        } catch (SQLException | ConnectionFactoryException e) {
            throw new StudyParticipationException(e.getMessage(), e);
        }
        return participationList;
    }

    }

is it good way to inject the UserService in the DAO like below as this is not related to DAO logic so it is a good way to write like that.

public  ParticipationDao(String userId, ConnectionFactory connectionFactory, UserService userService) {
        this.userId = userId;
        this.connectionFactory = connectionFactory;
        this.userService = userService;

    }

SUggest any good way. THank you

Pradeep
  • 1,192
  • 2
  • 12
  • 30
  • No it's not a design pattern I'd recommend. You should handle this kind of logic in the service layer itself and perform further queries based on the results if necessary. – Daisy Day Aug 03 '18 at 21:47

2 Answers2

0

Yes, it is good because your dependency is getting injected from outside, that is, from whoever will use the dao. In this way your dao don't need to know about construction details of the service itself and the service can change freely, but as long as it is provided dependency it is no issue from dao point of view.

Imagine that your dao constructed its own instance of user service. What will happen if the user service constructor gets modified, because it needs some more details? Then you should also modify your dao. This is not good. Dependency Injection was invented to face those issues.

The previous point is also useful for testing, for it allows easy mocking of the dependencies.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
  • yea true. generally we call the DAOs from the service class but here the scenario is differenent. service layer--> DAO--> another service layer – Pradeep Aug 03 '18 at 21:55
  • @Pradeep You can most probably use the userService in the service layer that used the dao, once the results are obtained from it. But also there isn't anything terribly wrong if you use service layer directly. – NiVeR Aug 03 '18 at 21:57
0

Good or bad are actually a relative qualifier and in software world, it's usually good if most engineers follow the same set of practice or pattern so that the code readers are easy to follow and operate on the code later. In your case, people usually keep the DAO as light as possible and if you need to enrich your DAO-fetched object with information from some other service, so better to do it in a Service, e.g. ParticipationService.

public ParticipationService(UserService userService, ParticipationDao Participation dao) {
    this.userService = userService;
    this.dao = dao;
}

public List<Participation> getParticipantDetails(Integer studyId) {
     return this.dao.getParticipantDetails(studyId).forEach(p -> {
         p.setUserName = userService.lookup(...);
     });
}
Duong Nguyen
  • 830
  • 6
  • 10