How to mock jdbctemplate.query() method? - spring

Mokito.when(jdbcTemplate.query(sql, new ParticipantMapper())).thenReturn(participantExistingList);
I am using above line of code for Mocking jdbcTemplate but its not working. Can some one will help how to mock jdbcTemplate.

Try to use ArgumentMatchers for all Arguments, like this:
Mokito.when(jdbcTemplate.query(any(String.class), any(ParticipantMapper.class)).thenReturn(participantExistingList);
Depending on your wish to focus the interaction, you may use e.g. eq() for your sql String. See here for JavaDoc.

Try doing this:
On your test class use:
#Mock
JdbcTemplate jdbcTemplate;
Then try:
Mokito.when(jdbcTemplate.query(sql, new ParticipantMapper())).thenReturn(participantExistingList);
If it still fails, try:
doReturn(participantExistingList).when(jdbcTemplate).query(sql, new ParticipantMapper());
Hope this helps

Its important to see the order of your parameters inside query() method.
In my case, I wanted to mock for the following line:
List<String> someList = jdbcTemplate.query(SQL_STRING,new Object[] { Id }, new MyCustomMapper());
So I mocked it the following way, taking care of the order of parameters passed
when(jdbcTemplate.query(any(String.class),(Object[]) anyVararg(),any(MyCustomMapper.class))).thenReturn(myList);

Related

Spring #Cacheable using "unless" for Mono results

I would like to use "unless" condition to avoid caching empty results.
my current method looks more or less similar to this:
#Cacheable(value = "items")
public Mono<List<Item>> getItems() {
return getItems().cache();
}
getItems() in this case is a method with a WebClient call returning a Mono<List>
I would like to add a "unless" condition to this #Cacheable so nothing gets cache if the List return by getItems is empty.
All examples I can find about using #result are non webflux examples, so I'm no sure how the actual condition should looks like.
I will assume here #result is actually a Mono<List> ?
Thanks a lot
Javier

What is the best way to populate Entity from DTO

I'm creating an order service, new to RestServices world.
I need to read the order model into a OrderDTO and persist in the DB.
For that I have a below method:
#PostMapping(produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<OrderDTO> createOrder(#Valid #RequestBody OrderDTO orderDTO) {
Order order = new Order(orderDTO);
Order createdOrder = orderService.createOrder(order);
OrderDTO createdOrderDTO = new OrderDTO(order);
ResponseEntity<OrderDTO> responseEntity = new ResponseEntity<OrderDTO>(createdOrderDTO, null, HttpStatus.CREATED);
return responseEntity;
}
Everything working fine, but I have concerns about the current design:
I'm reading an input into DTO
To Store the object I'm converting into Order object which will be persisted by Hibernate
Again to send the response back I'm converting the actual order object into DTO.
finally I will create 4-5 Objects per a request, if my app got 100 request it may run into memory issue.
How i can read the model data and persist efficiently?
In general, prefer DTO because of single responsibility principle, every object have its own responsibility and It's also clearer to separate View/Controller from Model objects
You can sometimes reduce OrderDTO, use an object that is both DTD and real Object,
It'll include DTD properties and also other properties that you can add using builder for example, I'm using #JsonIgnoreProperties(ignoreUnknown = true) to set only the DTD properties when object is created from request, e.g.:
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(Include.NON_NULL)
public class Order
You can also use JsonGetter/JsonProperty/JsonSetter to control what expected/returned
#JsonGetter and #JsonSetter are old alternatives to #JsonProperty.
I prefer a Mapper like Mapstruct:
OrderDtoMapper mapper = new OrderDTOMapper();
Order order = OrderDtoMapper.map(orderDto, Order.class);
and back:
OrderDTO createdOrderDTO = OrderDtoMapper.map(order, OrderDTO.class);
For me the code looks more readable ... and you do not have much to write for, as Mapstruct maps it automatically. Because it looks like you will map quite a lot ;)
Perhaps a mapper is worth a try: http://mapstruct.org/
I don't see any issue with the design.
As Nizet pointed out. Objects created are short lived.
Normally DTO and Entity design is followed to keep the UI and Service Layer separate.
In this way, you have the option to filter out sensitive info from being passed to the world like password, pin.
But if you want you can use Order entity directly in Controller class.
I won't suggest that but it's possible.

How to execute save operation immediatly in a #Transactional method

Say I have following code snippet
#Transactional
public void doSthing(){
// save an enetity to db
SomeClass entityA = new entityA();
mapper.save(entityA);
// I got null here!
Integer id = entityA.getId();
anotherEntity.setVal(id);
otherMapper.upate(anotherEntity)
}
as u see, I need the entityA's id to update another entity, but it's null at that time, if I remove the #Transactional it works, but I want the two operations in tansaction, which mean that i need spring rollback the doSthing() method on any opereation failured.
By default, methods annotated with #Transactional will rollback on any RuntimeException. So you can achieve the rollback by throwing some runtime exception under some condition.
If you want to rollback on any exception just add the following:
#Transactional(rollbackFor=Exception.class)
But what #Delinum said in the comment is true in general, that is, if you invoke a save on a dao/repository it should assign an #Id to the value object that you are saving, making it an entity.
I don't know what is type of your 'mapper' instance, but some implementations could work in a way that when you call save it doesn't change the original object, but rather it returns the persisted object. So instead of this:
mapper.save(entityA);
// I got null here!
Integer id = entityA.getId();
Use this:
Integer id = mapper.save(entityA).getId();

EF4.3 dependency injection when creating new objects yourself

I'm building an MVC3 application using the Entity Framework. In the application my controllers talk to a service layer. One of the controllers is a TournamentController which uses the TournamentService. This service has some standard methods such as CreateTournament, UpdateTournament etc.
When I want to insert a new tournament I want the view to have a dropdownlist of possible sports for which the tournament can be organised. So in the TournamentController's Create method I fill the ViewBag.Sports with a list of possible sports. Now to obtain this list of sports I use _tournamentService.GetAllSports(). In this GetAllSports() method of the TournamentService I want to create an instance of the SportService so I can 'forward' the question to the right service.
All services use dependency injection in the constructor to inject their own repository, like so:
private ITournamentRepository _repo;
public TournamentService(ITournamentRepository repo) {
_repo = repo;
}
My GetAllSports() method in the TournamentService looks like this:
public IEnumerable<Sport> GetAllSports() {
ISportService sportService = new SportService();
return sportService.GetSports();
}
The problem is that by calling the new SportService() it expects me to hand it an ISportRepository like in the TournamentService, where ninject creates the TournamentRepository. Now I could do the following:
public IEnumerable<Sport> GetAllSports() {
ISportService sportService = new SportService(new SportRepository());
return sportService.GetSports();
}
But the problem with that is that each repository expects an IContext, which is normally handled by ninject as well. Furthermore, I don't want two separate contexts to be instantiated.
A possible solution I found myself is to do this:
private ITournamentRepository _repo;
private ISportService _sportService;
public TournamentService(ITournamentRepository repo, ISportService sportService) {
_repo = repo;
_sportService = sportService
}
But there's only one method in my TournamentService class that would actually use the _sportService so I figure this is a bit overkill to make it a class attribute.
Keep it simple, inject ISportService to your controller and call sportService.GetSports() directly from the controller!
Your last solution valid. Inject the necessary service as part of the constructor.
And if you're worried about multiple contexts, don't let two separate contexts be created then.
In your Ninject binding:
Bind<ITournamentRepository>().To<TournamentRepository>().InRequestScope();
See https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope
The last piece is the important part. It will only create one instance of TournamentRepository for the current request. Any other requesters of TournamentRepository will get this instance.
If you're already doing this, you're set, otherwise, just add InRequestScope and you're done. (keeping in mind you'll need a reference to Ninject.Web.Common)
Hope that helps.
EDIT:
Remo is correct, I wouldn't call this from a service either. Just call for your lookup data from the controller and populate your view model. The InRequestScope advice still holds.

What is the difference between Collections from casted from a HashMap over entryset() and casted ArrayList for Jackson?

I am developing a Spring Rest application. One of my methods is that:
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody
Collection<Configuration> getConfigurationInJSON() {
Collection<Configuration> confList = new ArrayList<Configuration>();
...
I fill my confList and send it for GET request, it works. However when I want to keep that confList in a HashMap and send it after got it's entrySet as like that:
#RequestMapping(method = RequestMethod.GET)
public
#ResponseBody
Collection<Configuration> getAllConfigurationsInJSON() {
return configurationMap.values();
}
It gives me 406 error, so it means there is a wrong. What are the differences between that collections and why the second one is not same with first example?
For the sake of simplicity, can you just copy the values() collection?
new ArrayList<Configuration>(configurationMap.values());
Only thing that comes to my mind is that Spring expects mutable collection, but don't really understand why. Hard to say without debugging, try enabling org.springframework.web full logging.
The obvious difference is that configurationMap.values() is a Set.
You need to check if the JSON marshaller expects a List to be returned and is not able to marshal Set instances, as the marshaller will check the actual type of the returned value instead of the declared return type of the method, which is Collection.
By the way, isn't there any clue in the logs about this ?

Resources