javax.persistence.EntityNotFoundException: Spring Data JPA with Many to One Mapping - java

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

One-To-Many relationship with additional table and extra column. How to represent it in Java class?

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.

Unable to persist data into many-to-many mapping entity

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?

error with jpa spring many to many with extra columns

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

How to resolve java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer in Spring

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.

JPA get join table data condition [duplicate]

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;

Categories

Resources