Getting stream.map to return List Spring boot? - spring-boot

Trying to convert Author to Author Dto to return to List but it seems the only way it works is if I put Any or put it as a MutableList. Is there any way to fix this. Im using CrudRepository for my Author Repo
fun entityToDto(author: Author): AuthorDto? {
return AuthorDto(
id = author.id,
firstName = author.firstName,
lastName = author.lastName,
age = author.age,
publisherName = author.publisher.name
)
}
#GetMapping("/author")
fun getAllAuthors(): Any {
val authorList : List<Author> = authorRepo.findAll().toList()
return authorList.stream().map { x -> entityToDto(x) }.collect(Collectors.toList())
}

Related

Spring Boot Pagination is not working with custom DTO list

I am stuck with integrating pagination in Spring boot project.
Service Impl class
#Override
public Page<OnlineBuyProductReportItemDTO> generateOnlineBuyProductReport(String fromDate, String toDate, int pageNum, String sortField, String sortDir) {
Pageable pageable = PageRequest.of(pageNum - 1, 10,
sortDir.equals("asc") ? Sort.by(sortField).ascending()
: Sort.by(sortField).descending()
);
List<PurchaseOrder> purchaseOrderList = purchaseOrderRepository.searchPurchaseOrdersForOnlineBuyProductReport(
DateUtil.convertToDate(fromDate), DateUtil.convertToDate(toDate));
OnlineBuyProductReportItemDTO item = null;
List<OnlineBuyProductReportItemDTO> itemList = new ArrayList<OnlineBuyProductReportItemDTO>();
if(purchaseOrderList != null && purchaseOrderList.size() > 0) {
for (PurchaseOrder purchaseOrder : purchaseOrderList) {
item = new OnlineBuyProductReportItemDTO();
item.setOrderNumber(purchaseOrder.getOrderNumber());
item.setCreatedDate(DateUtil.convertDatetoStringSwissDate(purchaseOrder.getCreationTime()));
Address address = addressRepository.getAddressById(purchaseOrder.getBillingAddressId());
item.setCustomerName(address.getFullName());
item.setContactNumber(address.getTelephone());
List<OrderCart> orderCartList = orderCartRepository.getOrderCartByPurchaseOrderId(purchaseOrder.getId());
List<String> buyProductNameList = new ArrayList<String>();
if(orderCartList != null && orderCartList.size() > 0) {
for (OrderCart orderCart : orderCartList) {
buyProductNameList.add(orderCart.getProductName());
}
}
item.setProductName(buyProductNameList);
item.setPrice(purchaseOrder.getTotalPrice());
item.setStatus(purchaseOrder.getDeliveryStatus().getName());
itemList.add(item);
}
}
return new PageImpl<OnlineBuyProductReportItemDTO>(itemList, pageable,itemList.size());
}
Here I have fetch data from 3 database tables and after data processing I have added to these data to DTO List.
But, when after integrated with the front end, pagination options are displayed but did't work as expected.
All the pages containing same data set and also sorting options are not working as expected.
It seems this pageable part is not applying to the data processing.
Pageable pageable = PageRequest.of(pageNum - 1, 10,
sortDir.equals("asc") ? Sort.by(sortField).ascending()
: Sort.by(sortField).descending()
);
Is there any way to do this

Pass multiple Filters to Android Room Dao SQL Query from ViewModel with Repository

I am using the below to fetch Database rows to my Adapter, however I want to return rows from multi-filtered single query using either "LIKE" and/or "WHERE" and basically all sql query filter types, I can do one filter via MutableLiveData<String>();
end result would be like ...
#Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' postcode LIKE '%' || :postcode || '%' BETWEEN firstDate AND lastDate")
fun getFilteredRows(
suburb: String?,
postcode: String?,
firstDate: String?,
lastDate: String?): LiveData<List<MyTable>>
As per below, currently way only can pass one filter var.
ViewModel Class
class MyViewModel internal constructor(repository: MyRepository) : ViewModel()
//filter by suburb
var suburb = MutableLiveData<String>().apply {
//do I set as HashMap??
value = SUBURB
}
//LiveData Observer access
val filteredRows: LiveData<List<MyTable>> = suburb.switchMap {
//pass multiple filters to repository here
//but currently only can pass one string to repository
repository.getFilteredRows(it)
}
//MyViewModel function to set the suburb value
fun setSuburb(_suburb: String) {
suburb.value = _suburb
}
//companion object
companion object {
var SUBURB: String? = null
}
Repository Class
class Repository private constructor(private val dao: Dao)
//basic repo to dao communtication
fun getFilteredRows(suburb: String?) = dao.getFilteredRows(suburb)
Dao Interface
#Dao
interface Dao
//here I want to receive multiple Strings to do filtering within the query
#Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%'")
fun getFilteredRows(suburb: String?): LiveData<List<MyTable>>
I have tried with passing basic var Strings with no luck, seems only MutableLiveData is the way to pass variable to the Dao via ViewModel & Repository
** See Edit Below **
Not ideal to say the least, actually would not recommend, however, current work around is to "loop" through multiple MutableLiveData variables
ViewModel Class
var suburb = MutableLiveData<String>().apply { value = SUBURB }
var postcode = MutableLiveData<String>().apply { value = POSTCODE }
var limit = MutableLiveData<Int>().apply { value = LIMIT }
val filteredRows: LiveData<List<MyTable>> =
suburb.switchMap {
//set suburb MutableLiveData
var suburb = it
postcode.switchMap {
//set postcode MutableLiveData
var postcode = it
}
limit.switchMap {
//set limit MutableLiveData
var limit = it
}
repository.getFilteredRows(suburb, postcode, limit)
}
/// EDIT ANSWER ///
Using HashMap to pass multiple filters (Strings) to Dao SQl Query.
Tested a returned what was expected, so confirming this works.
Foreseeable issue is when needing to pass Strings & Int etc, may have to refer back to passing as Strings only & then do parse.ToInt() etc on Int String Values
build HashMap in my Fragment to pass to MyViewModel
lateinit var myModel: LiveData<MyTable>
var filters = HashMap<String, String>()
filters.put("suburb", myModel.value!!.suburb)
filters.put("postcode", myModel.value!!.postcode)
with(viewModel) {
//pass my HashMap to my ViewModel for update/change/set on filters MutableLiveData HashMap variable
setFilters(filters)
}
MyViewModel Class
//initilise filters MutableLiveData HashMap variable
var filters = MutableLiveData<HashMap<String, String>>().apply { value = FILTERS }
//function to update/change/set filters MutableLiveData HashMap variable
//see setFilters(filters) used in above Fragment
fun setFilters(_filters: HashMap<String, String>) {
filters.value = _filters
}
//foreach on passed HashMap via switchMap{}
val filtered: LiveData<List<MyTable>> = filters.switchMap {
//initilise variables
var suburb = ""
var postcode = ""
//foreach loop on HashCookie :)
for (filter in it) {
if(filter.key.equals("suburb")){
suburb = filter.value
}else if(filter.key.equals("postcode")) {
postcode = filter.value
}
}
//pass strings to Dao
repository.getFiltered(suburb, postcode)
}
//companion object
companion object {
var FILTERS: HashMap<String, String>? = null
}
Repository Class
//send variables to the Dao Interface
fun getFiltered(suburb: String?, postcode: String?) = dao.getFiltered(suburb, postcode)
Dao Interface
#Query("SELECT * FROM mytable WHERE suburb LIKE '%' || :suburb || '%' AND postcode LIKE '%' || :postcode || '%' ")
fun getFiltered(suburb: String?, postcode: String?): LiveData<List<MyTable>>

How do fetch the state with custome query? Corda application using Spring boot webserver- error while fetching the result

I have created the IOU in corda applicatiion, the IOU has ID,xml payload in body, partyName. NOW, i want to fetch the state with custome query that is basis on ID. NOTE- i am not using linearID.
Below is my API call- which gives me syntax error on. Can someone please correct me, what is the wrong thing that i am doing.
#GetMapping(value = ["getIous"],produces = [ MediaType.APPLICATION_JSON_VALUE])
private fun getTransactionOne(#RequestParam(value = "payloadId") payloadId: String): ResponseEntity<List<IOUState>> {
val generalCriteria = QueryCriteria.VaultQueryCriteria(Vault.StateStatus.ALL)
val results = builder { IOUState::iouId.equal(payloadId)
val customCriteria = QueryCriteria.VaultCustomQueryCriteria(results)}
val criteria = customCriteria.and(customCriteria)
val res = proxy.vaultQueryBy<IOUState>(criteria)
return ResponseEntity.ok(res)
}
I think the issue is because VaultCustomQueryCriteria is applicable only to StatePersistable objects. So you should use PersistentIOU instead of IOUState. Also, I could see incorrect use of brackets. Here is how your code should look like:
#GetMapping(value = ["getIous"],produces = [ MediaType.APPLICATION_JSON_VALUE])
private fun getTransactionOne(#RequestParam(value = "payloadId") payloadId: String): ResponseEntity<List<IOUState>> {
val generalCriteria = QueryCriteria.VaultQueryCriteria(Vault.StateStatus.ALL)
val results = builder {
val idx = IOUSchemaV1.PersistentIOU::iouId.equal(payloadId);
val customCriteria = QueryCriteria.VaultCustomQueryCriteria(idx)
val criteria = generalCriteria.and(customCriteria)
proxy.vaultQueryBy<IOUState>(criteria);
}
return ResponseEntity.ok(results)
}

Using the filter function in kotlin

so the past couple of hours, i have been trying to understand how the filter function works in kotlin and if it has any correlation with that of Java.
basically, i have a code that's written in java and i would love to have it transcribed to kotlin
private List<Order> getFilteredOrders(Courier courier) {
String[] glovoBoxKeywords = glovoBoxWords.toLowerCase().split(",");
List<Vehicle> allowedVehicles = Arrays.asList(MOTORCYCLE, ELECTRIC_SCOOTER);
return orders.stream()
.filter(order -> {
String description = order.getDescription().toLowerCase();
if (!courier.getBox()) {
return Arrays.stream(glovoBoxKeywords).noneMatch(description::contains);
}
return true;
})
.filter(order -> {
Location pickupLocation = order.getPickup();
Location deliveryLocation = order.getDelivery();
Double distance = calculateDistance(pickupLocation, deliveryLocation);
if (distance > longDeliveryDistance) {
return allowedVehicles.contains(courier.getVehicle());
}
return true;
})
.collect(Collectors.toList());
}
i tried this but i got at this, and was literally stuck :(
private fun findFilteredOrder(courier: Courier) : List<Order> {
val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)
orderList.filter { order ->
val description = order.getDescription().toLowerCase()
if(!courier.getBox()) {
}
true
}.filter {
val pickupLocation = it.getPickup()
val deliveryLocation = it.getDelivery()
val distance = calculateDistance(deliveryLocation, pickupLocation)
if(distance > longDeliveryDistance) {
courier.getVehicle() in allowedVehicles
}
true
}
}
Please this is my first attempt and doing something with kotlin, so please go easy guys. thanks, also i'd be appreciative if anyone could help me with informative stuff as to how to understand these kotlin functions better. let, apply, associateBy... etc.. THANKS
The filter function in Kotlin Collections has the same principle as other frameworks/libraries, including Java Streams. Given a predicate (a function from the type of the collection to Boolean) it will return a new collection with the elements matching the predicate. You can find more information and examples of other functions and operators in the official documentation and here.
Your code was almost there, I translate the Java Stream operation to Kotlin List and rewrite the return statements to remove the redundant if
private fun findFilteredOrder(courier: Courier) : List<Order> {
val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)
orderList.filter { order ->
val description = order.getDescription().toLowerCase()
courier.getBox() || glovoBoxKeywords.none { it in description }
}.filter { order ->
val pickupLocation = order.getPickup()
val deliveryLocation = order.getDelivery()
val distance = calculateDistance(deliveryLocation, pickupLocation)
distance <= longDeliveryDistance || courier.getVehicle() in allowedVehicles
}
}
I don't know why no one mentioned the use of labels: https://kotlinlang.org/docs/returns.html#break-and-continue-labels.
Since this question has a nice google ranking, I'll add what I was originally searching for.
The OP probably was aware that filter needs a predicate that returns a Boolean and that the filter will return a list with the items that pass the predicate (the items which the predicate returned true).
What he was not aware is that we can "emulate" Java returns through Kotlin labels:
private fun findFilteredOrder(courier: Courier) : List<Order> {
val glovoBoxKeyWords = glovoBoxWords.toLowerCase().split(",")
val allowedVehicles = listOf(Vehicle.ELECTRIC_SCOOTER, Vehicle.MOTORCYCLE)
orderList.filter shouldSkip#{ order ->
val description = order.getDescription().toLowerCase()
if (courier.getBox()) {
return#shouldSkip true
}
if (glovoBoxKeywords.none { it in description }) {
return#shouldSkip true
}
return#shouldSkip false
}.filter shouldSkip# { order ->
val pickupLocation = order.getPickup()
val deliveryLocation = order.getDelivery()
val distance = calculateDistance(deliveryLocation, pickupLocation)
if (distance <= longDeliveryDistance) {
return#shouldSkip true
}
if (courier.getVehicle() in allowedVehicles) {
return#shouldSkip true
}
return#shouldSkip false
}
}
Since Kotlin allows us to return in the last block line and the return keyword returns to the outer scope, it is pretty easy to:
filter {
startPutting >= someMagic && andComplex ||
verificationsThat.is { hardToUnderstand }.because {
weNeedToReturnHere
}
}
The labels allow us to be more verbose but also more clear.

MVC3 ajaxgrid scaffolding error, Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Objects.ObjectQuery'

I'm using MVC3 ajaxgrid scaffolding with EF4.1 code first and i've this error:
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Objects.ObjectQuery'
The code with the error in, is autogenerated:
public ActionResult GridData(int start = 0, int itemsPerPage = 20, string orderBy = "UserID", bool desc = false)
{
Response.AppendHeader("X-Total-Row-Count", repository.Users.Count().ToString());
ObjectQuery<User> users = (repository as IObjectContextAdapter).ObjectContext.CreateObjectSet<User>();
users = repository.Users.Include(u => u.Role); //ERROR HERE
users = users.OrderBy("it." + orderBy + (desc ? " desc" : ""));
return PartialView(users.Skip(start).Take(itemsPerPage));
}
This is the Users repository method and the Roles Foreign Key
public IQueryable<Entities.User> Users
{
get { return context.Users; }
}
public IQueryable<Entities.Role>Roles
{
get { return context.Roles; }
}
How can i resolve the conversion?
Get rid of the Lambda and use the related object:
var users = repository.Users.Include("Role"); //ERROR HERE
Assuming the entity User has a navigational property Role.
The reason is clear:
You have users variable with ObjectQuery<User> type then you assign that variable result of a query which is IQueryable<User>.
UPDATE:
Try the code below:
public ActionResult GridData(int start = 0, int itemsPerPage = 20, string orderBy = "UserID", bool desc = false)
{
Response.AppendHeader("X-Total-Row-Count", repository.Users.Count().ToString());
//ObjectQuery<User> users = (repository as IObjectContextAdapter).ObjectContext.CreateObjectSet<User>();
var users = repository.Users.Include(u => u.Role); //ERROR HERE
users = users.OrderBy("it." + orderBy + (desc ? " desc" : ""));
return PartialView(users.Skip(start).Take(itemsPerPage));
}

Resources