How to update select table using JPA custom single query - mysql

I want update work_withdraw table , set pending column of deposit
table value quantity column of work_withdraw table.First of all I
want to pick deposit table id that id contain all the details, I find
pending value from that id and that value set in work_withdraw table's
quantity column. I write Below type of Custom Query and code by in my
service class code it shows me type mismatch error, Required Long
found Unit,If I change the Return type of query to Long It throw
another "Update cannot return any thing"
WorkWithdrawRepository.kt
package com.nilmani.workload.repository
import com.nilmani.workload.entity.Deposit
import com.nilmani.workload.entity.WorkWithdraw
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.RequestParam
interface DepositRepository:JpaRepository<Deposit,Long> {
#Modifying
#Query("update WorkWithdraw Ww SET Ww.quantity=(SELECT d.pending FROM Deposit d WHERE d.id=Ww.id)")
fun getPendingStatus(#RequestParam("id")id:Long)
}
WorkWithdrawService.kt
package com.nilmani.workload.service
import com.nilmani.workload.entity.WorkWithdraw
import com.nilmani.workload.model.request.ReqUpdateWork
import com.nilmani.workload.model.request.ReqWorkWithdraw
import com.nilmani.workload.repository.DepositRepository
import com.nilmani.workload.repository.WorkerWithdrawRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
#Service
class WorkWithdrawService {
#Autowired
private lateinit var workerWithdrawRepository: WorkerWithdrawRepository
#Autowired
private lateinit var workerRepository: WorkerWithdrawRepository
#Autowired
private lateinit var depositRepository: DepositRepository
/**Update the work service*/
fun updateWorkWithdraw(reqUpdateWork: ReqUpdateWork): WorkWithdraw {
val updateWork = WorkWithdraw (
id = reqUpdateWork.id,
quantity = depositRepository.getPendingStatus(reqUpdateWork.id)
)
return workerWithdrawRepository.save(updateWork)
}
}
AdminWorkController.kt
package com.nilmani.workload.controller
import com.nilmani.workload.entity.AdvanceCash
import com.nilmani.workload.entity.Deposit
import com.nilmani.workload.entity.WorkWithdraw
import com.nilmani.workload.model.request.ReqUpdateWork
import com.nilmani.workload.model.request.ReqWorkWithdraw
import com.nilmani.workload.service.AdminService
import com.nilmani.workload.service.DepositService
import com.nilmani.workload.service.WorkWithdrawService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
#RestController
#RequestMapping("/admin")
class AdminWorkController {
#Autowired
private lateinit var workWithdrawService: WorkWithdrawService
#Autowired
private lateinit var depositService: DepositService
#Autowired
private lateinit var adminService: AdminService
/**Update the workWithdraw table when receive amterial*/
#PutMapping("/updateWithdraw-work")
fun updateWorkWithdraw(#ModelAttribute reqUpdateWork: ReqUpdateWork):ResponseEntity<*>{
val deza= workWithdrawService.updateWorkWithdraw(reqUpdateWork)
val respDeza = ReqUpdateWork(
deza.id,
deza.quantity
)
return ResponseEntity(respDeza,HttpStatus.OK)
}
}
RequestUpdatWork.kt
package com.nilmani.workload.model.request
data class ReqUpdateWork(
var id:Long=-1,
var quantity:Long=-1,
)
Deposit.kt
package com.nilmani.workload.entity
import java.time.LocalDateTime
import javax.persistence.*
#Entity
data class Deposit(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val totalPiece:Long=-1,
val totalDeposit:Long=-1,
#OneToOne(targetEntity = WorkWithdraw::class,cascade = [CascadeType.ALL])
val workWithdraw: WorkWithdraw,
var pending: Long =-1,
val depositTime:LocalDateTime= LocalDateTime.now()
)
WorkWithdraw.kt
package com.nilmani.workload.entity
import java.time.LocalDateTime
import javax.persistence.*
#Entity
data class WorkWithdraw(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val materialName:String="",
val quantity: Long =-1,
val withTime:LocalDateTime= LocalDateTime.now(),
#OneToOne(targetEntity = Worker::class,cascade = [CascadeType.ALL])
val worker: Worker?=null
)
I get error in my service class at this below point point
quantity = depositRepository.getPendingStatus(reqUpdateWork.id)
And the error is below
Type mismatch.
Required:
Long
Found:
Unit
I do not understand how to handle this type of situation,I tried to
solve this issue last 3 day's but not able to solve according
requirement
Do not know which type of parameter value passed inside #RequestParam
in my repository class

Related

Postman output "status":404,"error":"Not Found","path":"/api/employees"

the spring boot REST app with MySQL
I am trying to add record to DB and expect the record added and postman got it as output instead of the output "status":404,"error":"Not Found","path":"/api/employees" following is the classes
package com.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.service.EmployeeService;
import com.model.Employee;
#RestController
#RequestMapping("/api")
public class EmployeeController {
private EmployeeService employeeservice;
public EmployeeController(EmployeeService employeeservice) {
super();
this.employeeservice = employeeservice;
}
//build create Employee REST API
#PostMapping("/employees")
public ResponseEntity<Employee> saveEmployee(#RequestBody Employee employee)
{
return new ResponseEntity<Employee>(employeeservice.saveEmployee(employee), HttpStatus.CREATED);
}
}
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#EnableJpaRepositories(
basePackages = {"com.model"})
#SpringBootApplication(scanBasePackages = {"service.impl"})
public class RestapimysqlApplication {
public static void main(String[] args) {
SpringApplication.run(RestapimysqlApplication.class, args);
}
}
It doesn't look like you're scanning the package that contains your REST controller (i.e. com.controller), seems like you're only scanning the service.impl package on your RestapimysqlApplication class.
You should probably add the com.controller to the list of packages being scanned by Spring here:
#EnableJpaRepositories(basePackages = {"com.repository"})
#SpringBootApplication(scanBasePackages = {"service.impl", "com"})
#EntityScan({"com.model"})
public class RestapimysqlApplication {
...
}

Problem at scale: Jackson unable to resolve circular reference inspite of #JsonIdentityInfo when number of objects becomes large

Consider the simplified Kotlin code below wherein a circular reference is resolved during JSONification via #JsonIdentityInfo, when using Jackson. A class Index contains a list indices of other Indexes
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
import com.fasterxml.jackson.databind.ObjectMapper
import java.util.UUID
fun main() {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator::class, property = "id")
class Index() {
val id = UUID.randomUUID()
val neighbours = mutableListOf<Index>()
}
val n=1000 //does work for n=100
val indices = List(n) {Index()}
indices.forEach { it.neighbours.addAll(indices) }
ObjectMapper().writeValueAsString(indices)
}
The serialization fails for n=1000 but doesn't for n=100 hinting at a scaling issue.
I have gone through several SO answers as well as a very nice Baeldung blog (also found via SO) but those didn't help.
Why is there still a recursion error?
Interestingly the java version of the code works for both ns.
Is this a kotlin specific bug?
the gradle dependency being used
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.+"
java version
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class rough {
public static void main(String[] args) throws JsonProcessingException {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class Index {
public UUID id = UUID.randomUUID();
List<Index> neighbours = new ArrayList<>();
}
var n = 1000;
List<Index> indices = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
indices.add(new Index());
}
indices.forEach(index -> index.neighbours.addAll(indices));
new ObjectMapper().writeValueAsString(indices);
}
}

Flink Nested Json Serialization Issue

I'm trying to serialize flink Row to kafka, I don't have json schema with me, but have columns names, also Row can be accessed with index and fields, with plain json below code is working fine, however with nested json, for type Row, it is printing rowking and arity. I'm using JsonRowSerializationSchema with withTypeInfo builder.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.typeutils.RowTypeInfo;
import org.apache.flink.connector.kafka.sink.KafkaRecordSerializationSchema;
import org.apache.flink.formats.json.JsonRowSerializationSchema;
import org.apache.flink.types.Row;
public class JsonSerializerBuilder {
private final String[] columnNames;
public JsonSerializerBuilder(String[] columnNames) {
this.columnNames = columnNames;
}
public KafkaRecordSerializationSchema<Row> build() {
String outputTopic = "test_topic";
TypeInformation<Row> opTypeInfo = getTypeInformation();
JsonRowSerializationSchema jsonRowSerializationSchema =
JsonRowSerializationSchema.builder().withTypeInfo(opTypeInfo).build();
return KafkaRecordSerializationSchema.builder()
.setValueSerializationSchema(jsonRowSerializationSchema)
.setTopic(outputTopic)
.build();
}
private TypeInformation<Row> getTypeInformation() {
TypeInformation[] typeInformationArray = new TypeInformation[columnNames.length];
Arrays.fill(typeInformationArray, TypeInformation.of(Object.class));
return new RowTypeInfo(typeInformationArray, columnNames);
}
}
input: {"id": 1,"name":"mike","school_details":{"location": "uk","name": "test"}}
output: {"id": 1,"name":"mike","school_details":{"kind":"INSERT","arity":2}}
so basically Object TypeInformation is not working with Row type objects, how can I fix it.

Unable to insert in MySQL database using prepared statement

The code i used for data insertion.
The process working fine till the execute statement.Not sure why i am facing this issue.
package com.emandi.dao;
import java.sql.Date;
import java.sql.Statement;
import com.emandi.dbconnection.DBConnection;
import com.emandi.domain.Item;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class ItemDAO {
public void createItem(Item item) throws SQLException, ClassNotFoundException {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
}
Connection con = DBConnection.getConnection();
String query = "insert into item(item_id, item_name, total_quantity, available_quantity,date,user_id,item_type_id)"
+ " values (?, ?, ?, ?,?,?,?)";
PreparedStatement preparedStmt = con.prepareStatement(query);
Long a12= item.getItemId();
preparedStmt.setLong(1,a12);
preparedStmt.setString(2,item.getItemName());
preparedStmt.setDouble (3,item.getTotalQuantity());
preparedStmt.setDouble (4,item.getAvailableQuantity());
//java.sql.Date d= new java.sql.Date(format.parse(source).getTime());
java.util.Date utilStartDate = item.getDate();
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());
preparedStmt.setDate(5,sqlStartDate);
Long as = item.getUser().getUserId();
preparedStmt.setLong(6,as);
Long as1 = item.getItemType().getItemTypeId();
preparedStmt.setLong(7,as1);
System.out.println("Before");
preparedStmt.executeUpdate();
System.out.println("After");
}
}
The Class item is as follows
public class Item {
private Long itemId;
private User user;
private ItemType itemType;
private String itemName;
private Double totalQuantity;
private Double availableQuantity;
private Date date;
}
I have also now attached the output screenhot.enter image description here
Now i also updated the insert query using correct spelling for Total_quantity.
Still facing the issue

Null Body in SpringBoot WebMvcTest

I am getting a result from my unit test that I don't quite understand.
Controller Code
package com.rk.capstone.controllers;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.rk.capstone.model.domain.User;
import com.rk.capstone.model.services.user.IUserService;
/**
* REST Controller for /register endpoint
*/
#RestController
#RequestMapping("/register")
public class RegisterController {
private final IUserService userService;
public RegisterController(IUserService userService) {
this.userService = userService;
}
#RequestMapping(value = "/user", method = RequestMethod.POST)
public ResponseEntity<User> registerNewUser(#RequestBody User user) {
if (userService.findByUserName(user.getUserName()) == null) {
user = userService.saveUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
} else {
return ResponseEntity.status(HttpStatus.CONFLICT).body(null);
}
}
}
Unit Test Code:
package com.rk.capstone.controllers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rk.capstone.model.dao.UserDao;
import com.rk.capstone.model.domain.User;
import com.rk.capstone.model.services.user.IUserService;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Class Provides Unit Testing for RegisterController
*/
#RunWith(SpringRunner.class)
#WebMvcTest(RegisterController.class)
public class RegisterControllerTest {
#MockBean
private IUserService userService;
#Autowired
private MockMvc mockMvc;
private User user;
private String userJson;
#Before
public void setup() {
user = new User("rick", "k", "rick#email.com", "rkow", "abc123");
ObjectMapper objectMapper = new ObjectMapper();
try {
userJson = objectMapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
#Test
public void testRegisterNewUserPostResponse() throws Exception {
given(this.userService.findByUserName(user.getUserName())).willReturn(null);
given(this.userService.saveUser(user)).willReturn(user);
Assert.assertNotNull("Mocked UserService is Null", this.userService);
this.mockMvc.perform(post("/register/user").content(userJson).
contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isCreated()).
andDo(print()).andReturn();
}
}
The result of the print() is below, I do not understand why the Body is empty. I have tried numerous things I've read on other posts and blogs and no matter what I try the Body is always empty. Adding a Content-Type header in the controller response makes no difference.
MockHttpServletResponse:
Status = 201
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
What is confounding me even more, is when I run the actual application and perform a POST using PostMan to the /register/user endpoint the response contains the body and status code I expect, a User represented via JSON, e.g.
Status Code: 201 Created
Response Body
{
"userId": 1,
"firstName": "rick",
"lastName": "k",
"emailAddress": "rick#email.com",
"userName": "rk",
"password": "abc123"
}
Any help or ideas is appreciated, using SpringBoot 1.4.0.RELEASE.
UPDATE: For some reason the following mocked method call is returning null in the controller under test.
given(this.userService.saveUser(user)).willReturn(user);
This thread ultimately turned me on to a solution:
Mockito when/then not returning expected value
Changed this line:
given(this.userService.saveUser(user)).willReturn(user);
to
given(this.userService.saveUser(any(User.class))).willReturn(user);