request spring boot ,add rating - spring

i have to add rating to product by user,actually,i the user have the right to do the rating of product many times,now i will try to add rating to product once by user,if he haven't a rating to the product x,he can rate it,if he rated it in the past the value of rating will be updated:
my old request:
#Override
public RatingDto addRating(RatingDto rating) {
Optional<User> optionalUser = userRepo.findById(rating.getUser().getId());
Optional<Product> optionalProduct = productRepo.findById(rating.getProduct().getId());
rating.setUser(optionalUser.isPresent() ? optionalUser.get() : null);
rating.setProduct(optionalProduct.isPresent() ? optionalProduct.get() : null);
return ModelMapperConverter.map(ratingRepo.save(ModelMapperConverter.map(rating, Rating.class)), RatingDto.class);
}
my class rating:
public class Rating {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private double value;
#ManyToOne (cascade = CascadeType.MERGE)
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "userId")
private User user;
#ManyToOne (cascade = CascadeType.MERGE)
#OnDelete(action = OnDeleteAction.CASCADE)
#JoinColumn(name = "productId")
private Product product;
public Rating(double value, User user, Product product) {
this.setValue(value);
this.user = user;
this.product = product;
}
}
my class dto rating:
public class RatingDto {
private Long id;
private double value;
private User user;
private Product product;
public RatingDto(double value, User user, Product product) {
super();
this.setValue(value);
this.user = user;
this.product = product;
}
}
my table actual table in the database:
i need to have a table that contain rating of product by user and ,when he need to add a rating value,just the value will be updated

Related

How to postmapping in spring boot

I have 5 models:
admin
food
orders
payments
users
admin - admin can view/add/edit/delete food, and getting all users data(this part is done).
users - users can create orders.
so by my understanding, I did the mapping as follows:
users(1)-->orders(M)
orders(1)-->food(M)
orders(1)-->payments(1)
here is my code for all entity.
public class Users {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="user_id")
private Long usersId;
#Column(name="user_fName")
private String firstName;
#Column(name="user_lName")
private String lastName;
#Column(name="user_email")
private String email;
#Column(name="user_password")
private String password;
#Column(name="user_phnNumber")
private String phNumber;
#Column(name="user_address")
private String address;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#OneToMany(cascade = CascadeType.PERSIST,mappedBy= "users")
private Set<Orders> order;
}
public class Payments {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="payment_id")
private Long paymentId;
#Column(name="payment_amount")
private Long paymentAmount;
#Column(name="payment_date")
private Date paymentDate;
#Column(name="payment_transactionId")
private Long paymentTransactionId;
#OneToOne
#JoinColumn(name="order_id")
Orders orders;
public Payments(Long paymentAmount, Date paymentDate, Long paymentTransactionId,Orders orders1) {
super();
this.paymentAmount = paymentAmount;
this.paymentDate = paymentDate;
this.paymentTransactionId = paymentTransactionId;
this.orders = orders1;
}
}
public class Orders {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="order_id")
private Long orderId;
#ManyToOne
#JoinColumn(name="user_id")
Users users;
#OneToMany(cascade = CascadeType.ALL)
private Set<Food> food;
#OneToOne(cascade = CascadeType.ALL)
private Payments payments;
#Column(name="order_quantity")
private Long orderQuantity;
#Column(name="order_date")
private Date orderDate;
#Column(name="order_status")
private Boolean orderStatus;
public Orders(Long orderQuantity, Date orderDate, Boolean orderStatus,Users users1) {
super();
this.orderQuantity = orderQuantity;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.users = users1;
}
}
public class Food {
#Id
#SequenceGenerator(
name="food_sequence",
sequenceName="food_sequence",
allocationSize=1
)
#GeneratedValue(
strategy=GenerationType.SEQUENCE,
generator="food_sequence"
)
#Column(name="food_id")
private Long foodId;
#Column(name="food_name")
private String foodName;
#Column(name="food_desc")
private String foodDesc;
#Column(name="food_price")
private String foodPrice;
#Column(name="food_status")
private Boolean foodStatus;
#Column(name="food_img")
private String foodImg;
#ManyToOne
#JoinColumn(name="orders_id")
Orders orders;
public Food(String foodName,
String foodDesc,
String foodPrice,
Boolean foodStatus,
String foodImg,
Orders order1
) {
super();
this.foodName = foodName;
this.foodDesc = foodDesc;
this.foodPrice = foodPrice;
this.foodStatus = foodStatus;
this.foodImg = foodImg;
this.orders = order1;
}
}
So my Question: how to create an order. and when I see food table it has column orders_id. but here first admin will add food and then in the users side user will create orders using those food.
I am stuck at creating an order.
It would be better to remove the Payments column in the Orders class and the Orders column in the Food class.
Every order has a Payment, and you already do this by joining Order inside the Payments class. Likewise, there can be more than one Food in an Order, and you do this inside the Orders class.
To create an order, as you said, first the admin needs to add food to the table. After the food data is added to the table, the user will select food to create an order and you will add the selected food to the Order object's food attribute.(This could be better btw)
Then you will create a Payment with the Order that you created and manage the Payment separately.

Insert users id to the patient in Spring Boot

I can't insert the id of the currently logged-in user while making the patient data.
I want the user to be able to add his own patients, but the problem is that when I add a new patient, the column id_user is null
I tried lots of ways but couldn't add id_user to the patient.
What do I miss?
This is my User Entity:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int idUser;
private String firstName;
private String lastName;
private String username;
...
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
#JoinTable(name = "users_roles",
joinColumns = #JoinColumn(name = "id_user"),
inverseJoinColumns = #JoinColumn(name = "id_role"))
#JsonManagedReference
private Set<Role> roles = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<Patient> patients = new ArrayList<>();
public void add(Patient patient) {
if (patient != null) {
if (patients == null) {
patients = new ArrayList<>();
}
patients.add(patient);
patient.setUser(this);
}
}
Patient Entity:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_patient")
private int idPatient;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
...
#ManyToOne
#JoinColumn(name = "user_id", nullable = false)
private User user;
}
Controller
#RequestMapping("/addPatient")
public String addPatient(Model theModel, HttpServletRequest request) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userD = (UserDetails) auth.getPrincipal();
User u = userService.findByUsername(userD.getUsername());
request.getSession().setAttribute("id_user", u.getIdUser());
// int userId = user.getIdUser();
int userId = (int) request.getSession().getAttribute("id_user");
User user = new User();
user.setIdUser(userId);
Patient patient = new Patient();
patient.setUser(user);
theModel.addAttribute("patient", patient);
return "user/patients/add-patient-dashboard";
}
#PostMapping("savePatient")
public String savePatient(#ModelAttribute("patient") Patient thePatient, Model model) {
patientService.save(thePatient);
return "redirect:/user/allPatients";
}
I try editing the User service from:
#Override
public void save(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
to:
#Override
public void save(User user) {
List<Patient> patients = user.getPatients();
patients.forEach(patient -> user.add(patient));
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
if someone can help me resolve this I would appreciate it since I'm struggling for a very long time with this
Thanks to M Denium I finally solve the issue. I have moved the whole code from addUser to saveUser method:
#RequestMapping("/addPatient")
public String addPatient(Model theModel) {
Patient patient = new Patient();
theModel.addAttribute("patient", patient);
return "user/patients/add-patient-dashboard";
}
#PostMapping("savePatient")
public String savePatient(#ModelAttribute("patient") Patient thePatient, Model model, HttpServletRequest request) {
patientService.save(thePatient);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userD = (UserDetails) auth.getPrincipal();
User u = userService.findByUsername(userD.getUsername());
request.getSession().setAttribute("id_user", u.getIdUser());
int userId = (int) request.getSession().getAttribute("id_user");
User user = userService.findById(userId);
thePatient.setUser(user);
patientService.save(thePatient);
return "redirect:/user/allPatients";
}

Can I get the list of objects in relation #OneToMany?

I've got 2 classes: Device and Category. 1 Device can have 1 assigned category, but 1 category can have assigned many different devices.
#Entity
#Data
#Table(name = "devices")
public class Device implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
#Column(name="amount_of_items")
private Integer amountOfItems;
private BigDecimal price;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "category_id")
private Category category;
public Device(String name, String description, Integer amountOfItems, BigDecimal price, Category category){
this.name = name;
this.description = description;
this.amountOfItems = amountOfItems;
this.price = price;
this.category = category;
}
public Device() {}
}
#Entity
#Data
#Table(name = "categories")
public class Category implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
#OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
private List<Device> devices = new ArrayList<>();
public Category(String name, String description){
this.name = name;
this.description = description;
}
public Category() { }
}
Can I get the actual list of devices for one Category? The below code returns me a null list of devices:
Category category = new Category("Urzadzenia AGD", "tylko dla klientow premium");
categoryRepository.save(category);
Device device = new Device("pralka", "samoobslugowa", 50, new BigDecimal("220"),
category);
deviceRepository.save(device);
System.out.println(category.getDevies()) ---> returns NULL
Can I do it by calling a getter like above?
save method already return value after save in Database you can use this
Category category = new Category("Urzadzenia AGD", "tylko dla klientow premium");
category= categoryRepository.save(category);
Device device = new Device("pralka", "samoobslugowa", 50, new BigDecimal("220"),
category);
deviceRepository.save(device);
System.out.println(category.getDevies())
and you must be make setter and getter method in your class
after this you have problem stackover flow exciption becouse the all device called category and categore call Devices
you can used #JsonIgnore annotation
Like this :
#OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
#JsonIgnore
private List<Device> devices = new ArrayList<>();

Update the Foreign Key with JPA

I created 2 entities :
#Entity
#Table(name="products")
public class ProductEntity {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String productKeyId;
// many to one relationship with category
#ManyToOne
#JoinColumn(name = "category_id")
private CategoryEntity category;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int qty;
private String imgPath;
// getters & setters
}
And :
#Entity
#Table(name="categories")
public class CategoryEntity {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(length = 30, nullable = false)
private String categoryKeyId;
#Column(nullable = false)
private String name;
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name="parent_id", nullable=true)
private CategoryEntity parentCategory;
// allow to delete also subcategories
#OneToMany(mappedBy="parentCategory", cascade = CascadeType.ALL)
private List<CategoryEntity> subCategories;
//Here mappedBy indicates that the owner is in the other side
#OneToMany(fetch = FetchType.EAGER, mappedBy = "category", cascade = CascadeType.REMOVE)
private List<ProductEntity> products;
}
I have datas in the database generated :
Here is my Product table
And the category table
My issue is the following. I use a REST API to update the product and the category (if needed).
{
"name": "Pizza12",
"price": 25.0,
"qty": 15,
"imgPath": "anotherpathImage",
"category": {
"categoryKeyId": "VMz7EM6tNfoOAQtO1SHPYcH14jj0Cy",
"name": "Fish"
}
}
In my service I try to update both part separatelly :
#Override
public ProductDto updateProduct(String productKeyId, ProductDto productDto) {
// create a return object of type Product
ProductDto returnValue = new ProductDto();
// create Entity objects to request on the database
ProductEntity productEntity = productRepository.findByProductKeyId(productKeyId);
CategoryEntity categoryEntity = categoryRepository.findCategoryEntityByProductKeyId(productKeyId);
ModelMapper modelMapper = new ModelMapper();
if (productEntity == null)
throw new ApplicationServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());
productEntity.setProductKeyId(productKeyId);
productEntity.setName(productDto.getName());
productEntity.setPrice(productDto.getPrice());
productEntity.setQty(productDto.getQty());
productEntity.setImgPath(productDto.getImgPath());
// update the category
CategoryEntity updatedCategory = categoryRepository.save(categoryEntity);
productEntity.setCategory(updatedCategory);
// productEntity.setCategory(categoryEntity);
System.out.println("product entity : " + productEntity.toString());
ProductEntity updatedProduct = productRepository.save(productEntity);
updatedProduct.setCategory(updatedCategory);
returnValue = modelMapper.map(updatedProduct, ProductDto.class);
return returnValue;
}
Unfortunatelly, it doesn't seem to work as expected. The product is updated, the category remains the same.
I finally solved my Issue thanks to Janar and Repoker.
#Override
public ProductDto updateProduct(String productKeyId, ProductDto productDto) {
// create a return object of type Product
ProductDto returnValue = new ProductDto();
// create Entity objects to request on the database
ProductEntity productEntity = productRepository.findByProductKeyId(productKeyId);
CategoryEntity categoryEntity = categoryRepository.findByCategoryKeyId(productDto.getCategory().getCategoryKeyId());
//CategoryEntity categoryEntity = categoryRepository.findCategoryEntityByProductKeyId(productKeyId);
ModelMapper modelMapper = new ModelMapper();
if (productEntity == null)
throw new ApplicationServiceException(ErrorMessages.NO_RECORD_FOUND.getErrorMessage());
productEntity.setProductKeyId(productKeyId);
productEntity.setName(productDto.getName());
productEntity.setPrice(productDto.getPrice());
productEntity.setQty(productDto.getQty());
productEntity.setImgPath(productDto.getImgPath());
// update the category
CategoryEntity updatedCategory = categoryRepository.save(categoryEntity);
productEntity.setCategory(productEntity.getCategory());
// productEntity.setCategory(categoryEntity);
System.out.println("product entity : " + productEntity.toString());
ProductEntity updatedProduct = productRepository.save(productEntity);
updatedProduct.setCategory(updatedCategory);
returnValue = modelMapper.map(updatedProduct, ProductDto.class);
return returnValue;
}
I was not persisting the new values entered but the values that were initially set...

Record not inserted while using #ManyToOne mapping

I have 2 tables 'orders' and 'orderlines' and used bidirectional OneToMany mapping.When i save the order, record is successfully inserted into table 'orders'.But my 'orderlines' table is empty.No record is inserted.
This is the save operation code in Controller.
#RequestMapping(value = "ordersuccess", method = RequestMethod.POST)
public String processOrder(#ModelAttribute("order") Order order,
#ModelAttribute("cart") Cart cart,
BindingResult result) {
if (!result.hasErrors()) {
Set<OrderLine> orderLines = new HashSet<OrderLine>();
for(CartLine c : cart.getCartLines()) {
OrderLine line = new OrderLine();
line.setOrder(order);
line.setProduct(c.getProduct());
line.setProductPrice(c.getProduct().getPrice());
line.setTotalPrice(c.getPrice());
orderLines.add(line);
order.setOrderLines(orderLines);
}
orderService.save(order);
orderLineService.save(orderLine);
}
return "ordersuccess";
}
Can someone point me what wrong i am doing.
EDIT:
OrderLine.java
public class OrderLine {
#Id
#GeneratedValue
#Column(name="orderline_id")
private int orderline_id;
#ManyToOne
#JoinColumn(name = "order_id")
private Order order;
#ManyToOne(targetEntity = Product.class,
cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
#JoinTable(
name="products",
joinColumns=#JoinColumn(name="product_id")
)
private Product product;
)
Order.java
public class Order {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#OneToMany(mappedBy = "order")
private Set<OrderLine> orderLines;
//getter/setter
The orderLines object is created:
Set<OrderLine> orderLines = new HashSet<OrderLine>();
You then add lines to it:
orderLines.add(line);
But it never attributed to an order or sent to the service layer.
Also the OrderLine.product mapping should be like this
public class OrderLine {
#Id
#GeneratedValue
#Column(name="orderline_id")
private int orderline_id;
#ManyToOne
#JoinColumn(name = "order_id")
private Order order;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "product_id")
private Product product;
}
and Order.orderLines should have a cascade:
public class Order {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private Set<OrderLine> orderLines;
}
You then need to save the orderLines:
order.setOrderLines(orderLines);
and save the order:
orderService.save(order);
When order is saved it will cascade the orderlines and the associated product too.
If you have bidirectional associations don't forget to set both sides.

Resources