I populated the cart and cartitem classes using this json request -
{
"userId": "1246772",
"cartItemRequests": [
{
"itemId": "12345",
"quantity": 5
}
],
"discount": {
"promoCode": "MYPROMO",
"discountPercentage": 0
}
}
I am seeing this error in the response - javax.persistence.EntityNotFoundException: Unable to find cart.model.CartItem with id d3931cb8-ab81-4c1b-b722-841c7fcf2f77.
When I debugged the code , I was able to see "d3931cb8-ab81-4c1b-b722-841c7fcf2f77" the cartItem list present in cart. However when I save using Spring Data JPA , I see the above error
#Entity
public class CartItem {
#Id
private String id;
private String itemId;
private int quantity;
#ManyToOne
private Cart cart;
public CartItem() {
this.id = UUID.randomUUID().toString();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
}
#Entity
public class Cart {
#Id
private String id;
private String userId;
#OneToMany(fetch = FetchType.LAZY)
private List<CartItem> cartItems;
#Embedded
private Discount discount;
public Cart() {
this.id = UUID.randomUUID().toString();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public List<CartItem> getCartItems() {
return cartItems;
}
public void setCartItems(List<CartItem> cartItems) {
this.cartItems = cartItems;
}
public Discount getDiscount() {
return discount;
}
public void setDiscount(Discount discount) {
this.discount = discount;
}
}
can you update your code with below one n check:---
#OneToMany(mappedBy = "Cart", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private List<CartItem> cartItems;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
private Cart cart;
Related
I'm working on Calorie Counter Application. After logging in, each user will only have access to their meals.
I have a database like below:
I'll display all information like the template below.
Meal 1
Chicken breast
100g
130kcal
Apple
200g
100kcal
Tomatoes
300g
30kcal
Meal 2
Chicken breast
100g
130kcal
Apple
200g
100kcal
Tomatoes
300g
30kcal
User class:
#Entity
#Table(name = "users")
public class User {
private int id;
private String username;
private String password;
private int age;
private String email;
private Gender gender;
private List<Meal> meals;
public User() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "gender")
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
#OneToMany(mappedBy = "user")
public List<Meal> getMeals() {
return meals;
}
public void setMeals(List<Meal> meals) {
this.meals = meals;
}
private enum Gender{
MALE,
FEMALE
}
}
Meal class:
#Entity
#Table(name = "meals")
public class Meal {
private int id;
private LocalDate date = LocalDate.now();
private User user;
private List<MealFoodProduct> mealFoodProducts;
public Meal() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#OneToMany(mappedBy = "foodProduct")
public List<MealFoodProduct> getMealFoodProducts() {
return mealFoodProducts;
}
public void setMealFoodProducts(List<MealFoodProduct> mealFoodProducts) {
this.mealFoodProducts = mealFoodProducts;
}
#Column(name = "created_at")
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
#ManyToOne
#JoinColumn(name = "user_id")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
FoodProduct class:
#Entity
#Table(name = "food_products")
public class FoodProduct {
private int id;
private String productName;
private Double proteins;
private Double fats;
private Double carbohydrates;
private Double calories;
public FoodProduct() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "product_name")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#Column(name = "proteins")
public Double getProteins() {
return proteins;
}
public void setProteins(Double proteins) {
this.proteins = proteins;
}
#Column(name = "fats")
public Double getFats() {
return fats;
}
public void setFats(Double fats) {
this.fats = fats;
}
#Column(name = "carbohydrates")
public Double getCarbohydrates() {
return carbohydrates;
}
public void setCarbohydrates(Double carbohydrates) {
this.carbohydrates = carbohydrates;
}
#Override
public String toString() {
return productName;
}
#Column(name = "calories")
public Double getCalories() {
return calories;
}
public void setCalories(Double calories) {
this.calories = calories;
}
}
MealFoodProcuct class
#Entity
#Table(name = "meals_food_products")
public class MealFoodProduct {
private Meal meal;
private FoodProduct foodProduct;
private double weight;
public MealFoodProduct() {
}
#ManyToOne
#JoinColumn(name = "meal_id")
public Meal getMeal() {
return meal;
}
public void setMeal(Meal meal) {
this.meal = meal;
}
#ManyToOne
#JoinColumn(name = "food_product_id")
public FoodProduct getFoodProduct() {
return foodProduct;
}
public void setFoodProduct(FoodProduct foodProduct) {
this.foodProduct = foodProduct;
}
#Column(name = "food_product_weight")
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
My questions:
Is it correct way to connect these classes?
What should be an ID in MealFoodProduct class?
I would suggest you to use composite identifiers with #IdClass for the MealFoodProduct entity.
#Entity
#Table(name = "meals_food_products")
#IdClass( MealFoodProductPK.class )
public class MealFoodProduct {
#Id
#ManyToOne
#JoinColumn(name = "meal_id")
public Meal getMeal() {
return meal;
}
#Id
#ManyToOne
#JoinColumn(name = "food_product_id")
public FoodProduct getFoodProduct() {
return foodProduct;
}
// ...
}
public class MealFoodProductPK implements Serializable {
private Meal meal;
private FoodProduct foodProduct;
public MealFoodProductPK(Meal meal, FoodProduct foodProduct) {
this.meal = meal;
this.foodProduct = foodProduct;
}
public MealFoodProductPK() {
}
//Getters, setters, equals, hashCode are omitted for brevity
}
Additional details see here.
P.S. Other parts of your mapping look good.
I have 2 entities - Book and Publisher which have a many-to-many relationship. Besides the ids of these entities in the mapping entity, I want to store additional attribute such as bookFormat. So I created a mapping entity BookPublisher and created a composite key entity BookPublisherId. Now, when I want to persist the data using JSON data from my rest controller, I am not able to persist the data correctly. In my JSON data, I am passing the following:
{
"name": "Book14",
"authors": [
{
"firstName": "book14FirstName",
"lastName": "book14LastName"
}
],
"publishers": [
{
"publisher": {
"name": "Pearson1"
},
"format": "Paperback"
}
]
}
Here's the Book entity:
#Entity
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull
private String name;
#ManyToMany(cascade = CascadeType.ALL)
#JsonBackReference
private Set<Author> authors;
#OneToMany(mappedBy = "book")
private List<Review> reviews;
#OneToMany(mappedBy = "book")
private Set<BookPublisher> publishers;
public Book() {
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Review> getReviews() {
return reviews;
}
public void setReviews(List<Review> reviews) {
this.reviews = reviews;
}
public Set<Author> getAuthors() {
return authors;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
public Set<BookPublisher> getPublishers() {
return publishers;
}
public void setPublishers(Set<BookPublisher> publishers) {
this.publishers = publishers;
}
}
Here's the Publisher entity:
#Entity
public class Publisher {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
#OneToMany(mappedBy = "publisher")
private Set<BookPublisher> publishedBooks;
public Publisher() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<BookPublisher> getPublishedBooks() {
return publishedBooks;
}
public void setPublishedBooks(Set<BookPublisher> publishedBooks) {
this.publishedBooks = publishedBooks;
}
}
Here's the BookPublisher entity:
#Entity
public class BookPublisher {
#EmbeddedId
private BookPublisherId bookPublisherId;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("bookId")
private Book book;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("publisherId")
private Publisher publisher;
private String format;
public BookPublisher() {
}
public BookPublisher(Book book, Publisher publisher, String format) {
this.book = book;
this.publisher = publisher;
this.format = format;
}
public BookPublisherId getBookPublisherId() {
return bookPublisherId;
}
public void setBookPublisherId(BookPublisherId bookPublisherId) {
this.bookPublisherId = bookPublisherId;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
Here's the code where I am trying to save the Book entity I receive in the rest controller:
public Book addBook(Book book) {
Set<BookPublisher> toAddPublishers = new HashSet<>();
for(BookPublisher publisher : publishers) {
Publisher addedPublisher = publisherRepository.save(publisher.getPublisher());
BookPublisher toAddBookPublisher = bookPublisherRepository.save(new BookPublisher(book, addedPublisher, publisher.getFormat()));
toAddPublishers.add(toAddBookPublisher);
}
book.setPublishers(toAddPublishers);
Book addedBook = bookRepository.save(book);
return addedBook;
}
When I try to call this method, I see that the BookPublisher entity is not being persisted in the database. What is the correct way to add such data?
I can not say anything definite by the looks of your code but is your addBook inside a transactional scope? Also, why have you not set any cascades for your relationships?
My issue is "Could not set field value [2] value by reflection : [class com.shopctr7.backend.entity.ShopimportProductId.productId] setter of com.shopctr7.backend.entity.ShopimportProductId.productId"
ShopimportProductId class:
#Embeddable
public class ShopimportProductId implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5618056056848194639L;
#Column(name = "shopimport_id")
private Long shopimportId;
#Column(name = "product_id")
private Long productId;
public ShopimportProductId() {
}
public Long getShopimportId() {
return shopimportId;
}
public void setShopimportId(Long shopimportId) {
this.shopimportId = shopimportId;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
}
ShopimportProduct class:
#Entity
#Table(name = "shopimport_product")
public class ShopimportProduct implements Serializable {
/**
*
*/
private static final long serialVersionUID = 17304033239166680L;
#EmbeddedId
private ShopimportProductId shopimportProductId;
#ManyToOne
#MapsId("shopimportId")
private Shopimport shopimport;
#ManyToOne
#MapsId("productId")
private Product product;
private Long price;
public ShopimportProduct() {
}
private Integer amount;
public ShopimportProductId getShopimportProductId() {
return shopimportProductId;
}
public void setShopimportProductId(ShopimportProductId shopimportProductId) {
this.shopimportProductId = shopimportProductId;
}
public Shopimport getShopimport() {
return shopimport;
}
public void setShopimport(Shopimport shopimport) {
this.shopimport = shopimport;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Long getPrice() {
return price;
}
public void setPrice(Long price) {
this.price = price;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
}
Shopimport class
#Entity
#Table(name = "shopimport")
public class Shopimport extends UserDateAudit {
/**
*
*/
private static final long serialVersionUID = -7067616970499289402L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#OneToMany(mappedBy = "product")
private List<ShopimportProduct> shopimportProducts;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<ShopimportProduct> getShopimportProducts() {
return shopimportProducts;
}
public void setShopimportProducts(List<ShopimportProduct> shopimportProducts) {
this.shopimportProducts = shopimportProducts;
}
}
Product class
#Entity
#Table(name = "product")
public class Product extends UserDateAudit {
/**
*
*/
private static final long serialVersionUID = -979803757359739557L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
private String name;
#NotNull
private Long price;
#NotNull
private Integer amount;
private String imageUrl;
#OneToMany(mappedBy = "shopimport")
private List<ShopimportProduct> shopimportProducts;
#Enumerated(EnumType.STRING)
#Column(length = 60)
private ProductType productType;
public Product() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getPrice() {
return price;
}
public void setPrice(Long price) {
this.price = price;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public ProductType getProductType() {
return productType;
}
public void setProductType(ProductType productType) {
this.productType = productType;
}
public List<ShopimportProduct> getShopimportProducts() {
return shopimportProducts;
}
public void setShopimportProducts(List<ShopimportProduct> shopimportProducts) {
this.shopimportProducts = shopimportProducts;
}
}
My test
User user = userRepository.findById(2L)
.orElseThrow(() -> new UsernameNotFoundException("User not found with id : "));
Shopimport shopImport = new Shopimport();
shopImport.setUser(user);
Shopimport ShopImportResult = shopImportRepository.save(shopImport);
Product product1 = productRepository.findById(2L)
.orElseThrow(() -> new UsernameNotFoundException("User not found with id : "));
ShopimportProduct shopimportProduct = new ShopimportProduct();
shopimportProduct.setShopimport(ShopImportResult);
shopimportProduct.setProduct(product1);
shopimportProduct.setAmount(100);
shopimportProduct.setPrice(1000L);
shopImportProductRepository.save(shopimportProduct);
Product product2 = productRepository.findById(2L)
.orElseThrow(() -> new UsernameNotFoundException("User not found with id : "));
ShopimportProduct shopimportProduct2 = new ShopimportProduct();
shopimportProduct2.setShopimport(ShopImportResult);
shopimportProduct2.setProduct(product2);
shopimportProduct2.setAmount(200);
shopimportProduct2.setPrice(2000L);
shopImportProductRepository.save(shopimportProduct2);
My issue at shopImportProductRepository.save(shopimportProduct);
Could not set field value [2] value by reflection : [class com.shopctr7.backend.entity.ShopimportProductId.productId] setter of com.shopctr7.backend.entity.ShopimportProductId.productId
MenuModel
#Entity
#Table(name="M_MENU", uniqueConstraints={#UniqueConstraint(columnNames={"NAME"})})
public class MenuModel {
private Integer id;
private String code;
private String name;
private String controller;
private Integer parent_id;
#Id
#Column(name="ID")
#GeneratedValue(strategy=GenerationType.TABLE, generator="M_MENU")
#TableGenerator(name="M_MENU", table="M_SEQUENCE",
pkColumnName="SEQUENCE_NAME", pkColumnValue="M_MENU_ID",
valueColumnName="SEQUENCE_VALUE", allocationSize=1, initialValue=0
)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name="CODE")
public String getCode() {
return code;
}
public void setCode(String kode) {
this.code = kode;
}
#Column(name="NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="CONTROLLER")
public String getController() {
return controller;
}
public void setController(String controller) {
this.controller = controller;
}
#Column(name="PARENT_ID")
public Integer getParent_id() {
return parent_id;
}
public void setParent_id(Integer parent_id) {
this.parent_id = parent_id;
}
}
UserAccessModel
#Entity
#Table(name="M_USER_ACCESS")
public class UserAccessModel {
private Integer id;
//join table role
private Integer idRole;
private RoleModel roleModel;
//join table menu
private Integer idMenu;
private MenuModel menuModel;
#Id
#Column(name="ID")
#GeneratedValue(strategy=GenerationType.TABLE, generator="M_USER_ACCESS")
#TableGenerator(name="M_USER_ACCESS", table="M_SEQUENCE",
pkColumnName="SEQUENCE_NAME", pkColumnValue="M_USER_ACCESS_ID",
valueColumnName="SEQUENCE_VALUE", allocationSize=1, initialValue=0
)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name="ID_ROLE")
public Integer getIdRole() {
return idRole;
}
public void setIdRole(Integer idRole) {
this.idRole = idRole;
}
#ManyToOne
#JoinColumn(name="ID_ROLE", nullable=true, updatable=false, insertable=false)
public RoleModel getRoleModel() {
return roleModel;
}
public void setRoleModel(RoleModel roleModel) {
this.roleModel = roleModel;
}
#Column(name="ID_MENU")
public Integer getIdMenu() {
return idMenu;
}
public void setIdMenu(Integer idMenu) {
this.idMenu = idMenu;
}
#ManyToOne
#JoinColumn(name="ID_MENU", nullable=true, updatable=false, insertable=false)
public MenuModel getMenuModel() {
return menuModel;
}
public void setMenuModel(MenuModel menuModel) {
this.menuModel = menuModel;
}
}
MenuDaoImpl
#Override
public List<MenuModel> searchByRole(Integer idRole) {
// TODO Auto-generated method stub
Session session = this.sessionFactory.getCurrentSession();
List<MenuModel> menuModelListRole = new ArrayList<MenuModel>();
Criteria userAccessCriteria = session.createCriteria(UserAccessModel.class,"UA");
Criteria menuCriteria = userAccessCriteria.createCriteria("menuModel","M");
userAccessCriteria.add(Restrictions.eq("idRole", ""+idRole+""));
ProjectionList properties = Projections.projectionList();
properties.add(Projections.property("M.id"));
properties.add(Projections.property("M.name"));
properties.add(Projections.property("M.code"));
properties.add(Projections.property("M.controller"));
properties.add(Projections.property("M.parent_id"));
menuCriteria.setProjection(properties);
menuModelListRole = menuCriteria.list();
return menuModelListRole;
}
I want to get result of the following sql:
select M.ID ID, M.NAME NAME, M.CODE CODE, M.CONTROLLER CONTROLLER,
M.PARENT_ID PARENT from M_MENU M join M_USER_ACCESS UA on UA.ID_MENU
= M.ID where UA.ID_ROLE="+idRole+"
I got error in method searchByRole in menuModelListRole = menuCriteria.list();. How can i resolve the problem?
Here private Integer idRole; is of Integer type, but you are passing idRole as String in Restrictions.eq("idRole", ""+idRole+""). SO you are getting java.lang.String cannot be cast to java.lang.Integer in Spring
Changing you restriction value from Restrictions.eq("idRole", ""+idRole+"") to Restrictions.eq("idRole", idRole) should solve your problem.
When I send a GET request in POSTMAN to get all my child entity (Town) the parent entity (Province) is not shown in the JSON response.
This is my controller.
#RequestMapping(value ="api/v1/town",method = RequestMethod.GET)
public ResponseEntity<List<Town>> getAllTowns() {
List<Town> towns = townService.getAllTowns();
if(towns.isEmpty()) {
return new ResponseEntity<List<Town>>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<Town>>(towns, HttpStatus.OK);
}
And these are my entities.
Parent Class
#Entity
#Table(name = "PROVINCE")
public class Province {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "PROVINCE_ID")
private long id;
private String name;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "province", targetEntity = Town.class)
#JsonManagedReference("Province-Town")
private List<Town> towns;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Town> getTowns() {
return towns;
}
public void setTowns(List<Town> towns) {
this.towns = towns;
}
}
Child Class
#Entity
#Table(name = "TOWN")
public class Town {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "TOWN_ID")
private long id;
private String name;
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "PROVINCE_ID")
#JsonBackReference("Province-Town")
private Province province;
private long kilometer;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
public long getKilometer() {
return kilometer;
}
public void setKilometer(long kilometer) {
this.kilometer = kilometer;
}
}
The response that I'm getting is like this
{
"id" : 1,
"name" : "Some Town",
"kilometer" : 350
}
What I'm expecting is
{
"id" : 1,
"name" : "Some Town",
"province" : {
//Province data.....
}
"kilometer" : 350
}
I was able to show something like this, but the Objects that I used are not Spring-data-jpa entities, just simple POJOs.
Is there any problem with my Entities? Or is there anything else?
Swap #JsonBackReference and #JsonManagedReference. Basically:
#JsonManagedReference
private Province province;
#JsonBackReference
private List<Town> towns;