How to correctly join tables in Spring Boot - java

I have a User, and the user has Expenses. In expenses table I want to have the expense id, the user who made the expense and the amount of expense. In the user table I want user id, his username, his current balance and list of all expenses he's made.
I want to join those 2, but I don't know how to correctly reference user, therefore user form Expense class is always null.
First, I send post request to create a user:
{
"username":"abcd",
"balance":"100"
}
then I want to create an expense, but here I'm not sure how to correctly send a User:
{
"username":"abcd",
"id":"1",
"balance":"100",
"amount":"20"
}
and this doesn't work, then I tried like this:
{
"User":{
"username":"abcd",
"id":"1",
"balance":"100"
},
"amount":"20"
}
and that didn't work either.
This is the User class:
#Entity
#Table(name = "Users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Username is mandatory")
private String username;
private Double balance = 0.0;
#OneToMany(mappedBy = "user")
private List<Expense> expenses;
...
I removed getters and setters from here.
Here is the Expense class:
#Entity
#Table(name = "Expenses")
public class Expense {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
private Double amount;
...
For saving the expense I use .save() from JpaRepository<Expense, Long> and for retrieveing everyting I use .findAll().
The result is always the same: get for all expenses gives
{
"id": 1,
"user": null,
"amount": 20
}
and get for all users gives
{
"id": 1,
"username": "abcd",
"balance": 100,
"expenses": []
}
Now I'm not sure whether I'm sending the requests the wrong way or joining the tables the wrong way or both.
EDIT: here is ExpenseController:
#RestController
public class ExpenseController {
#Autowired
IExpenseService expenseService;
#GetMapping("/expenses")
public List<Expense> findExpenses() {
return expenseService.findAll();
}
#PostMapping("/expenses")
public void createNewExpense(#RequestBody Expense expense) {
expenseService.createNewExpense(expense);
}
}
createNewUser(...) from ExpenseService
#Override
public void createNewExpense(Expense expense) {
repository.save(expense);
}
and ExpenseRepository:
#Repository
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
}
UserController:
#RestController
public class UserController {
#Autowired
IUserService userService;
#GetMapping("/users")
public List<User> findUsers() {
return userService.findAll();
}
#GetMapping("/users/{id}")
public User findUserById(#PathVariable Long id) {
return userService.findById(id);
}
#PostMapping("/users")
public ResponseEntity<Object> createUser(#RequestBody User user) {
if (userService.checkIfUsernameIsTaken(user)) {
Map<String, Object> response = new HashMap<>();
response.put("status", HttpStatus.NOT_ACCEPTABLE);
response.put("errors", "Username is already taken");
response.put("timestamp", new Date());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
} else {
userService.createNewUser(user);
User currentUser = userService.findById(userService.findByUsername(user.getUsername()));
Map<String, Object> response = new HashMap<>();
response.put("id", currentUser.getId());
response.put("username", currentUser.getUsername());
response.put("balance", currentUser.getBalance());
response.put("expenses", currentUser.getExpenses());
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
#DeleteMapping("/users/{id}")
public void deleteUser(#PathVariable Long id) {
userService.deleteUser(id);
}
#PutMapping("/users/{id}/{balance}")
public void updateBalance(#PathVariable Long id, #PathVariable Double balance) {
userService.updateBalance(id, balance);
}
}
the rest of the User model is the same as the Expense model.

Try to send post request with this payload (field 'user' begins with a small letter), and i think the 'id' field in user object should be enough
{
"user":{
"username":"abcd",
"id":"1",
"balance":"100"
},
"amount":"20"
}
EDIT: Also you need to add #JsonIgnoreProperties("expenses") to your Expense entity to prevent jackson from recursive reading json
#Entity
#Table(name = "Expenses")
public class Expense {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#JsonIgnoreProperties("expenses")
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
private Double amount;
.....

Related

JAVA / SPRING JPA : Not returning dependence at creation

First, I apologize if my english is unclear ; I am french.
I also am a very junior developer, and this is my first real personal project with no tutorial or whatsoever.
I am having some trouble with my Rest api.
I use java 11 and Spring/JPA
I have two DO classes that each represent a table in the database : Artist and Country.
An artist can have several nationalities, and a country can have several artist born in it.
So that means : many to many.
I joined them with an Association table ; ArtistNationality, that is also a class.
I know I could do without an additional class but, since in my app some relations also have some extra-fields (like the year of an award) I decided that all many to many relationships would be materialized the same way, by "join"classes (sorry I really have an hard time to explain in english)
When I create an Artist, I want my response json to contain the created artist with all its nationalities. But it always comes null.
The creation works fine. But here is the response :
What is odd is the results of my API call.
Here is the result of POST method :
{
"artistFirstName": "OH",
"artistLastName": "Test",
"artistBiography": "Je suis un test.",
"artistBirthDate": "1380-11-10",
"artistDeathDate": "1500-11-12",
"artistNationalities": [],
"artist_ID": 3
}
As you can see, nationalities come null, always.
What is expected, is the same as when I do a find or findall :
{
"artistFirstName": "OH",
"artistLastName": "Test",
"artistBiography": "Je suis un test.",
"artistBirthDate": "1380-11-10",
"artistDeathDate": "1500-11-12",
"artistNationalities": [
{
"nationality": {
"countryId": 1,
"countryName": "Andorre",
"countryShortCode": "AD",
"countryFlagFileName": "ad_16.png"
},
"nationalityId": 5
},
{
"nationality": {
"countryId": 12,
"countryName": "Autriche",
"countryShortCode": "AT",
"countryFlagFileName": "at_16.png"
},
"nationalityId": 6
}
],
"artist_ID": 3
}
What I don't understand is that my save method returns the result of a "find" method so why isn't it the same ?? Find and findall work perfectly, and the insertion also works fine.
Here are the DataObject classes, I shortened them to leave only the fields related to question but of course they all come with their constructors and getters/setter stuff :
Artist class :
#Entity
#Table(name = "artist")
public class Artist implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_artist")
private final Integer ARTIST_ID;
#OneToMany(targetEntity = ArtistNationality.class, mappedBy = "artistIdAsForeignKey", cascade = CascadeType.ALL)
#JsonManagedReference
private List<ArtistNationality> artistNationalities;
Artist DTO
public class ArtistDto {
private final Integer ARTIST_ID;
private String artistFirstName;
private String artistLastName;
private String artistBiography;
private String artistBirthDate;
private String artistDeathDate;
private List<NationalityDto> artistNationalities;
Country class :
#Entity
#Table(name = "country")
public class Country implements Serializable {
#Id
#Column(name = "id_country")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private final Integer COUNTRY_ID;
#OneToMany(targetEntity = ArtistNationality.class, mappedBy = "countryIdAsForeignKey", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JsonBackReference
private List<ArtistNationality> artistsComingFromCountry;
** COUNTRY DTO **
public class CountryDto {
private int countryId;
private String countryName;
private String countryShortCode;
private String countryFlagFileName;
ArtistNationality class :
#Entity
#Table(name="artist_x_nationality")
public class ArtistNationality implements Serializable {
#Id
#GeneratedValue
#Column(name="id_nationality")
private final Integer NATIONALITY_ID;
#ManyToOne (fetch = FetchType.LAZY)
#JsonBackReference
#JoinColumn(name= "fk_nationality_to_artist")
private Artist artistIdAsForeignKey;
#ManyToOne (fetch = FetchType.LAZY)
#JsonBackReference
#JoinColumn(name="fk_nationality_to_country")
private Country countryIdAsForeignKey;
Nationality Dto:
public class NationalityDto {
private final Integer NATIONALITY_ID;
private CountryDto nationality;
ArtistService :
#Service
public class ArtistServiceImpl implements IArtistService {
#Autowired
private IArtistDao artistDao;
#Autowired
private IArtistDoDtoMapper mapper;
#Autowired
private IArtistValidator validator;
#Autowired
private IArtistNationalityDao nationalityDao;
#Override
#Transactional(readOnly = true)
public List<ArtistDto> findAll() {
List<ArtistDto> resultList = new ArrayList<ArtistDto>();
List<Artist> artistsFromDatabase = artistDao.findAll();
if (artistsFromDatabase != null && !artistsFromDatabase.isEmpty()) {
resultList = mapper.mapDoListToDto(artistsFromDatabase);
}
return resultList;
}
#Override
#Transactional(readOnly = true)
public ArtistDto find(final int id) {
Optional<Artist> optArtistFromDatabase = artistDao.findById(id);
if (!optArtistFromDatabase.isPresent()) {
throw new ResourceNotFoundException();
}
Artist artistFromDatabase = optArtistFromDatabase.get();
ArtistDto result = mapper.mapDoToDto(artistFromDatabase);
return result;
}
#Override
#Transactional(rollbackFor = Exception.class)
public ArtistDto save(final ArtistDto objDto) {
if(validator.isValidForDatabase(objDto)){
//Save without nationalities (mapper does not map it);
Artist artistToSave = mapper.mapDtoToDo(objDto);
int artistId = artistDao.save(artistToSave).ARTIST_ID();
//Add the id of the artist to all his nationalities, then save the nationalities
for (NationalityDto nationality : objDto.getArtistNationalities()){
ArtistNationality doNationality = new ArtistNationality(nationality.getNationalityId());
doNationality.setArtistIdAsForeignKey(new Artist(artistId));
doNationality.setCountryIdAsForeignKey(new Country(nationality.getNationality().getCountryId()));
nationalityDao.save(doNationality);
}
ArtistDto returnArtist = this.find(artistId);
return returnArtist;
}
throw new InsertionException("Invalid object. Could not insert into database.");
}
Mappers :
#Override
#Transactional(rollbackFor = Exception.class)
public ArtistDto mapDoToDto(final Artist pDataObject) {
ArtistDto artistDto = new ArtistDto(pDataObject.ARTIST_ID());
if (artistValidator.isNotNullAndNotEmpty(pDataObject.getArtistFirstName())) {
artistDto.setArtistFirstName(pDataObject.getArtistFirstName());
}
if (artistValidator.isOptionPresent(pDataObject.getArtistLastName())) {
artistDto.setArtistLastName(pDataObject.getArtistLastName());
}
if (artistValidator.isOptionPresent(pDataObject.getArtistBiography())) {
artistDto.setArtistBiography(pDataObject.getArtistBiography());
}
if (artistValidator.isOptionPresent(pDataObject.getArtistBirthDate())) {
artistDto.setArtistBirthDate(pDataObject.getArtistBirthDate());
}
if (artistValidator.isOptionPresent(pDataObject.getArtistDeathDate())) {
artistDto.setArtistDeathDate(pDataObject.getArtistDeathDate());
}
List<NationalityDto> artistNationalities = new ArrayList<NationalityDto>();
if (artistValidator.isOptionPresent(pDataObject.getArtistNationalities())) {
System.out.println("yes, we're in !");
for (ArtistNationality nationality : pDataObject.getArtistNationalities()) {
NationalityDto nDto = new NationalityDto(nationality.getNationalityId());
CountryDto cDto = countryMapper.mapDoToDto(nationality.getCountryIdAsForeignKey());
nDto.setNationality(cDto);
artistNationalities.add(nDto);
}
}
artistDto.setArtistNationalities(artistNationalities);
return artistDto;
}
/**
* Note : we add nationality separately since we do not have Artist's ID yet.
*/
#Override
#Transactional(rollbackFor = Exception.class)
public Artist mapDtoToDo(final ArtistDto pDataTransfertObject) {
System.out.println(pDataTransfertObject.toString());
Artist artist = new Artist(pDataTransfertObject.getARTIST_ID());
if (artistValidator.isNotNullAndNotEmpty(pDataTransfertObject.getArtistFirstName())) {
artist.setArtistFirstName(pDataTransfertObject.getArtistFirstName());
}
if (artistValidator.isOptionPresent(pDataTransfertObject.getArtistLastName())) {
artist.setArtistLastName(pDataTransfertObject.getArtistLastName());
}
if (artistValidator.isOptionPresent(pDataTransfertObject.getArtistBiography())) {
artist.setArtistBiography(pDataTransfertObject.getArtistBiography());
}
if (artistValidator.isOptionPresent(pDataTransfertObject.getArtistBirthDate())) {
artist.setArtistBirthDate(pDataTransfertObject.getArtistBirthDate());
}
if (artistValidator.isOptionPresent(pDataTransfertObject.getArtistDeathDate())) {
artist.setArtistDeathDate(pDataTransfertObject.getArtistDeathDate());
}
return artist;
}
This is the Json I send to my controller :
{
"ARTIST_ID" : null,
"artistFirstName":"OH",
"artistLastName":"Test",
"artistBiography":"Je suis un test.",
"artistBirthDate":"1380-11-10",
"artistDeathDate": "1500-11-12",
"artistNationalities": [{
"nationality": {
"countryId" : 1
}
},
{"nationality":{
"countryId": 12
}
}
]
}
I also had to find a trick to save nationalities after artist because when I sent nationalities to database, jpa did not automatically add the saved artist to the nationality and the nationality was saved only with the country data, as you can see in the save method and the dto to do mapper.
I am sorry if it is not really clear, I do my best in english, thank you for understanding.
If your find and findAll is working then, you should be able to override return from save and use find jpa method using the artist id returned by save in your service layer that way you will have a complete json to return.

Not Found when Returning Embedded Collection MongoDB Spring Boot

I am creating an application with embedded review documents inside Course documents with Spring Data Rest and MongoDB but I am unable to get reviews for a course. Here is my controller:
#Controller
#RequestMapping("/courses")
public class CourseController {
private final CourseRepository courseRepository;
public CourseController(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
#PatchMapping("/add-review")
public List<Review> addReview(#RequestBody AddReviewDto addReviewDto) {
Course course = courseRepository.findById(addReviewDto.getCourseId()).get();
Review review = new Review(new ObjectId().toString(), addReviewDto.getReview());
List<Review> reviews = course.getReviews();
reviews.add(review);
course.setReviews(reviews);
return courseRepository.save(course).getReviews();
}
#GetMapping("/{id}/reviews")
public List<Review> getAllReviewsForCourse(#PathVariable String id) {
Course course = courseRepository.findById(id).get();
return course.getReviews();
}
}
Here is the Course model:
#Getter
#Setter
#Document(collection = "courses")
#AllArgsConstructor
#NoArgsConstructor
public class Course {
public Course(#NotNull String code, #NotNull String name,
#NotNull String type, List<Review> reviews) {
this.code = code;
this.name = name;
this.type = type;
this.reviews = reviews;
}
#Id
private String id;
#NotNull
private String code;
#NotNull
private String name;
#NotNull
private String type;
private List<Review> reviews = new ArrayList<>();
}
And Review model:
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public class Review {
#Id
private String id;
private String reviewText;
private String userName;
private String userId;
public Review(String id, Review other) {
this.id = id;
this.reviewText = other.reviewText;
this.userId = other.userId;
this.userName = other.userName;
}
}
When I send a request to http://localhost:8888/courses/605dc41f54beac4412cabadc, I successfully get reviews inside the course object as follows:
{
"code": "CS 101",
"name": "Introduction to Programming",
"type": "Lecture",
"reviews": [
{
"reviewText": "dfgsfgdgdg",
"userName": "yigit",
"userId": "604a9382777a83b08307c7e8"
}
]
}
But when I try to send the request to localhost:8888/courses/605dc41f54beac4412cabadc/reviews, I get 404 not found.
I debugged my code and seen that the code is running the correct controller, finding the course object and its reviews are visible in debugger but when I return course.getReviews(), it doesnt work.
You should be sending to http://localhost:8888/courses/605dc41f54beac4412cabadc/reviews
Try to open this URL in your browser
of course you get 404. Because your #RequestMapping is "/courses". try send the request to http://localhost:8888/courses/{id}/reviews
Turns out, I have used #Controller instead of #RestController...

How to send only the ID the of main nested objects in the body request in spring boot

I'm creating eCommerce for merchants using spring boot with JPA.
I have an issue while creating the order service.
I want to only pass the ID of the nested objects in the request body instead of sending the full nest objects because the size will be extremely big.
Here is my code.
Merchant can do many orders
Order
#Entity
#Table(name = "Orders")
#XmlRootElement
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Order extends BasicModelWithIDInt {
#Basic(optional = false)
#Column(name = "Quantity")
private Integer quantity;
#Basic(optional = false)
#Size(min = 1, max = 150)
#Column(name = "Notes")
private String notes;
#JoinColumn(name = "ProductID", referencedColumnName = "ID")
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JsonIgnoreProperties
private Product productID;
#JoinColumn(name = "MerchantID", referencedColumnName = "ID")
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Merchent merchent;
#JoinColumn(name = "OrderSatusID", referencedColumnName = "ID")
#ManyToOne(optional = false, fetch = FetchType.EAGER)
private OrderStatus orderStatus;
// Getters and Setters
}
Order Holder
public class OrderHolder {
#NotNull
private Order order;
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
OrderRepo
public interface OrderRepo extends JpaRepository<Order, Integer> {
}
Order Controller
#RestController
#RequestMapping(value = "order", produces = MediaType.APPLICATION_JSON_VALUE)
public class OrderRestController extends BasicController<OrderHolder>{
#Autowired
private OrderRepo orderRepo;
#PostMapping("create")
public ResponseEntity<?> create(#RequestBody #Valid OrderHolder orderHolder, Principal principal) throws GeneralException {
log.debug( "create order {} requested", orderHolder.toString());
Order order = new Order();
order = orderHolder.getOrder();
System.out.println("###############"+order);
try {
order = orderRepo.save(order);
log.info( "Order {} has been created", order );
} catch (Exception e) {
log.error( "Error creating Order: ", e );
e.printStackTrace();
throw new GeneralException( Errors.ORDER_CREATION_FAILURE, e.toString() );
}
return ResponseEntity.ok( order );
}
}
I need request body to look like the below instead of including the full Merchant and Product objects inside the request.
You can make use of JsonView to return only id of product and merchant
public class OrderView {}
...
public class Product{
#Id
#JsonView(OrderView.class)
private Integer id
private String otherFieldWithoutJsonView
...
}
and then in your controller
#PostMapping("create")
#JsonView(OrderView.class) // this will return the product object with one field (id)
public ResponseEntity<?> create(#RequestBody #Valid OrderHolder orderHolder, Principal principal) throws GeneralException {
...
}
hope this can help you
Just have a separate contract class.
public class OrderContract {
private int merchantID;
private String notes;
....
//getter, setters
}
public class OrderHolder {
#NotNull
private OrderContract orderContract;
public OrderContract getOrderContract() {
return orderContract;
}
public void setOrder(OrderContract orderContract) {
this.orderContract = orderContract;
}
}
And before making a call to the Repository , translate from OrderContract to Order.
I would like to share something regarding this.
I have searched a lot on internet and tried lot of things, but the solution given here suited well for this scenario.
https://www.baeldung.com/jackson-deserialization
You need to create a Custom-deserializer for your model by extending StdDeserializer from com.fasterxml.jackson.databind.deser.std.StdDeserializer, where you just want to pass id's and not the whole object in the request.
I have given below example for User Model with Address object.
User(long userId, String name, Address addressId)
Address(long addressId, String wholeAddress)
Writing Deserializer for User class
public class UserDeserializer extends StdDeserializer<User> {
public User() {
this(null);
}
public User Deserializer(Class<?> vc) {
super(vc);
}
#Override
public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode node = p.getCodec().readTree(p);
long id = 0;
long addressId = (Long) ((IntNode) node.get("addressId")).numberValue().longValue();
return new User(id, name, new Address(addressId, null)
}
Now you have to use
#JsonDeserialize(using = UserDeserializer.class)
public Class User {
...
}
POST request
Before custom deserialization
{
"name" : "Ravi",
"addressId" : { "id" : 1}
}
After custom Deserialization
{
"name" : "Ravi",
"addressId" : 1
}
Also while GET /user/:id call you will get the whole obj like
{
"name" : "Ravi",
"addressId" : { "id" : 1, "wholeAddress" : "Some address"}
}

How to make a Restful API to handle many-to-many relation in Spring Boot?

In my Spring boot project, I have two tables names- doctors and patients. In these tables, I have following attributes-
Now, the thing is I want to create a many to many relation between these two tables for appointment as one doctor can have many patients and one patient can have appointment of multiple doctors. So, to handle this problem, I have created another table named appointment which will have doctorId and patientId as foreign key.
I need to create appointment by using JSON request body like below-
So, for this purpose I have created a model class like below-
Appointment.java
#Entity
#Table(name = "appointments")
public class Appointment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
private Long appointedDoctorId;
#NotNull
private Long appointedPatientId;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "doctorId", nullable = false)
private Doctor doctor;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "patientId", nullable = false)
private Patient patient;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAppointedDoctorId() {
return appointedDoctorId;
}
public void setAppointedDoctorId(Long appointedDoctorId) {
this.appointedDoctorId = appointedDoctorId;
}
public Long getAppointedPatientId() {
return appointedPatientId;
}
public void setAppointedPatientId(Long appointedPatientId) {
this.appointedPatientId = appointedPatientId;
}
public Doctor getDoctor() {
return doctor;
}
public void setDoctor(Doctor doctor) {
this.doctor = doctor;
}
public Patient getPatient() {
return patient;
}
public void setPatient(Patient patient) {
this.patient = patient;
}
}
Here's the Repository class-
AppointmentRepository .java
#Repository
public interface AppointmentRepository extends JpaRepository<Appointment, Long> {
Page<Appointment> findByDoctorId(Long id, Pageable pageable);
}
Here's my Service interface-
AppointmentService .java
public interface AppointmentService {
public Page<Appointment> getAllAppointmentByDoctorId(#PathVariable(value = "doctorId") Long id, Pageable pageable);
public Appointment createAppointment(#Valid #RequestBody Appointment createAppointmentRequest);
}
Here's the implementation of my Service class-
AppointmentServiceImpl.java
#Service
public class AppointmentServiceImpl implements AppointmentService {
#Autowired
AppointmentRepository appointmentRepository;
#Override
public Page<Appointment> getAllAppointmentByDoctorId(Long id, Pageable pageable) {
return appointmentRepository.findByDoctorId(id, pageable);
}
#Override
public Appointment createAppointment(#Valid Appointment createAppointmentRequest) {
return appointmentRepository.save(createAppointmentRequest);
}
}
And at last I have this Controller class-
Appointment.java
#RestController
#RequestMapping("/api")
public class AppointmentController {
#Autowired
AppointmentService appointmentService;
#GetMapping("/doctors/{doctorId}/appointments")
public Page<Appointment> getAllAppointmentsByDoctorId(#PathVariable(value = "id") Long id, Pageable pageable){
return appointmentService.getAllAppointmentByDoctorId(id, pageable);
}
#PostMapping("/insert/new/appointments")
public Appointment createAppointment(#Valid Appointment createAppointmentRequest) {
return appointmentService.createAppointment(createAppointmentRequest);
}
}
But whenever I run the project and do POST request for creating the Appointment using the mentioned request body, it is showing the following response-
So, I need to know what's the problem in my code and how can I create an appointment POST request by giving the doctorId and patientId like the way I mentioned in JSON RequestBody request.

Update multiple users by passing list of User ids

I am trying to update some user information by passing List of User-Ids as parameter
i want to update isActive field of User fo which i am passing the user ids.
Below is my controller
#PutMapping
#ResponseStatus(HttpStatus.OK)
#RequestMapping("/UserUpdate")
public ResponseEntity<?> updateUsers(List<Long> userIds) {
**userService.updateUsers(userIds);**
return ResponseEntity.ok(200);
}
updateUsers() is a method in my Service where i have to write the logic
I tried something like below but it's not working
public void updateUsers(List<Long> userIds) {
List<Users> userList= userRepository.findAll();
for (Long i : userIds) {
for ( Users user : userList)
{
if(userRepository.findById(i) != null)
{
user.setIsActive(9L);
user.setUserName("Update Test");
}
my dto
public class UserDto {
private List<Users> userList;
private String appName="Users Project";
// getters and setters removed for brevity
And my Users entity class
#Entity
#Table(name="USERS")
public class Users {
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
#Column(name="NAME")
private String userName;
#Column(name="ACTIVE")
private Long isActive;
// getters and setters removed for brevity
Alternatively you can use the following code
#Modifying
#Query("update Users u set u.isActive = ?1, u.userName = ?2 where u.userId in ?3")
void updateUsers(Long isActive, String userName, List<Long> userId);
Add this code in your userRepository and use the method.
public void updateUsers(List<Long> userIds) {
for (Long i : userIds) {
User user = userRepository.findById(i);
if(user != null){
user.setIsActive(9L);
user.setUserName("Update Test");
// call your update method here (this is not stated in your code)
}
}
}

Categories