Reputation: 568
Consider these two following options:
Option #1: Autowiring the required Services in Controller
@Controller
@RequestMapping(value="/foo")
public class FooController {
@Autowired
private FooService fooService;
@Autowired
private BarService barService;
@Autowired
private BazService bazService;
@RequestMapping(method=RequestMethod.GET)
public String getFoo(...) {
Foo foo = fooService.getFooInstance(...);
List<Foo> foos = fooService.getFooList(foo);
List<Bar> bars = barService.getBarList(foo);
Baz baz = bazService.getBaz(foo);
...
return "view/foo/index.jsp";
}
}
Option #2: Autowiring dependent Services for UoW in specific Service
@Controller
@RequestMapping(value="/foo")
public class FooController {
@Autowired
private FooService fooService;
@RequestMapping(method=RequestMethod.GET)
public String getFoo(...) {
Foo foo = fooService.getFooInstance(...);
FooDTO fooInfo = fooService.getFooAllInformation(foo);
List<Foo> foos = fooInfo.getFoos();
List<Bar> bars = fooInfo.getBars();
Baz baz = fooInfo.getBaz();
...
return "view/foo/index.jsp";
}
}
@Service
public class FooServiceImpl implements FooService {
@Autowired
private FooRepository fooRepository;
@Autowired
private BarService barService;
@Autowired
private BazService bazService;
...
@Override
@Transactional
public FooDTO getFooAllInformation(Foo foo) {
List<Foo> foos = getFooList(foo);
List<Bar> bars = barService.getBarList(foo);
Baz baz = bazService.getBaz(foo);
...
}
}
Well, currently I'm using Option #1 and everything's working just fine. But I'm wondering if this approach is good enough or not. Do any of them have any significant advantages over the other one? I should mention that I'm aware of @Transactional
for the INSERT
part of the Service (which I have omitted here). But what about just Reading the data.
Upvotes: 1
Views: 139
Reputation: 691685
The second option is both cleaner, faster, and safer. It's basically using the facade pattern.
Cleaner because it moves code business code outside of the UI layer, in the service layer, where it belongs.
Faster because, since everything is made in the same transaction, you'll save transaction openings and closings, and benefit from the transactional cache (assuming you use an ORM to fetch the data you need). And it's of course even faster if the UI and service layers are on sepaate JVMs.
Safer because, since everything is in the same transaction, each service will get data from the same consistent database "snapshot". In the first option, you could have the first method return a foo which doesn't exist anymore when the second service is called. Of course, this depends on the transaction isolation level of your database, but it'll always be safer than doing it in several transactions.
Upvotes: 4