error with jpa spring many to many with extra columns - java

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

Related

Going around the many-to-many relationship in Spring boot, but no new entity is created

I'm using spring boot to construct a database using AWS RDS as well. I want to track down how many stars a user gives to different products. I learnt to go around the many-to-many relationship by creating a table connecting two one-to-many other tables. For this reason, I have created the following tables:
When a user rates a product, an api is called through the put command in order to track down which user(uid) rates which product(pid). When the product(pid) is not rated by anyone, a rate_item is created that contains the pid and also the uid. However, when another user (with a different uid) rates the same product (same pid), the rate_item is updated, which is a problem becausse supposedly, a new row containing the same pid and a different uid should be created, as seen in the following (user with "uid 1" has already rated the same product and when user with "uid 2" rates the same product, the entity gets updated, but not like a new entity is created):
ProductEntity:
#Entity
#Table(name = "product")
public class ProductEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "pid",nullable = false)
private Integer pid;
#Column(name = "name", nullable = false)
private String name;
#Column(name="theme", nullable = false)
private String theme;
#Column(name="color", nullable = false)
private String color;
#Column(name="sizeZero", nullable = true)
private String sizeZero;
#Column(name="sizeOne", nullable = true)
private String sizeOne;
#Column(name="sizeTwo", nullable = true)
private String sizeTwo;
#Column(name="sizeThree", nullable = true)
private String sizeThree;
#Column(name="description",nullable = false)
private String description;
#Column(name = "image_url", nullable = false)
private String imageUrl;
#Column(name = "price",nullable = false)
private BigDecimal price;
#Column(name = "stock",nullable = false)
private Integer stock;
public ProductEntity(CreateProductData createProductData) {
this.pid = createProductData.getPid();
this.name = createProductData.getName();
this.theme =createProductData.getTheme();
this.color=createProductData.getColor();
this.sizeZero=createProductData.getSizeZero();
this.sizeOne =createProductData.getSizeOne();
this.sizeTwo =createProductData.getSizeTwo();
this.sizeThree =createProductData.getSizeThree();
this.description =createProductData.getDescription();
this.imageUrl = createProductData.getImageUrl();
this.price = createProductData.getPrice();
this.stock = createProductData.getStock();
}
public ProductEntity(){
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTheme() {
return theme;
}
public void setTheme(String productType) {
this.theme = productType;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getSizeZero() {
return sizeZero;
}
public void setSizeZero(String sizeZero) {
this.sizeZero = sizeZero;
}
public String getSizeOne() {
return sizeOne;
}
public void setSizeOne(String smallSize) {
this.sizeOne = smallSize;
}
public String getSizeTwo() {
return sizeTwo;
}
public void setSizeTwo(String mediumSize) {
this.sizeTwo = mediumSize;
}
public String getSizeThree() {
return sizeThree;
}
public void setSizeThree(String largeSize) {
this.sizeThree = largeSize;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
}
UserEntity:
#Entity
#Table(name="User")
public class UserEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="uid",nullable = false)
private Integer uid;
#Column(name="username", nullable = false)
private String username;
#Column(name="email", nullable = false, unique = true)
private String email;
#Column(name="password", nullable = false)
private String password;
#Column(name = "firebase_uid", nullable = false)
private String firebaseUid;
#Column(name= "emailVerified", nullable = false,columnDefinition = "boolean default false")
private Boolean emailVerified=false;
#Column(name="subscribed", nullable = false)
private Boolean subscribed;
public UserEntity(UserEntity tempUserEntity){
this.uid=tempUserEntity.getUid();
this.firebaseUid=tempUserEntity.getFirebaseUid();
this.email=tempUserEntity.getEmail();
}
public UserEntity(CreateFirebaseUserData createFirebaseUserData){
this.username=createFirebaseUserData.getUsername();
this.email=createFirebaseUserData.getEmail();
this.password=createFirebaseUserData.getPassword();
this.firebaseUid= createFirebaseUserData.getFirebaseUid();
this.subscribed=createFirebaseUserData.getSubscribed();
}
public UserEntity(){
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirebaseUid() {
return firebaseUid;
}
public void setFirebaseUid(String firebaseUid) {
this.firebaseUid = firebaseUid;
}
public Boolean getEmailVerified() {
return emailVerified;
}
public void setEmailVerified(Boolean emailVerified) {
this.emailVerified = emailVerified;
}
public Boolean getSubscribed() {
return subscribed;
}
public void setSubscribed(Boolean subscribed) {
this.subscribed = subscribed;
}
}
RatingEntity:
#Entity
#Table(name="Rating")
public class ProductsRatedByUserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="pruid")
private Integer pruid;
#OneToOne
#JoinColumn(name="pid",nullable = false)
private ProductEntity product;
#ManyToOne
#JoinColumn(name="uid",nullable = false)
private UserEntity user;
#Column
private Integer starsGiven;
#Column(name="total_stars", nullable = false)
private Integer totalStars;
#Column(name="total_num_of_users_who_rated", nullable = false)
private Integer totalNumOfUsersWhoRated;
#Column(name="average_stars")
private BigDecimal averageStars;
public ProductsRatedByUserEntity(UserEntity userEntity, ProductEntity productEntity, Integer numOfStars){
this.product=productEntity;
this.user=userEntity;
this.starsGiven=numOfStars;
this.totalStars=numOfStars;
this.totalNumOfUsersWhoRated=1;
this.averageStars=BigDecimal.valueOf(this.getTotalStars()).divide(BigDecimal.valueOf(this.getTotalNumOfUsersWhoRated()));
}
public ProductsRatedByUserEntity(ProductEntity product,UserEntity user,Integer numOfStars,Integer newTotalNumOfStars, Integer newTotalNumberOfUsers, BigDecimal averageStars){
this.product=product;
this.user=user;
this.starsGiven=numOfStars;
this.totalStars=newTotalNumOfStars;
this.totalNumOfUsersWhoRated=newTotalNumberOfUsers;
this.averageStars=averageStars;
}
public ProductsRatedByUserEntity(){
}
public Integer getPruid() {
return pruid;
}
public void setPruid(Integer plbuid) {
this.pruid = plbuid;
}
public ProductEntity getProduct() {
return product;
}
public void setProduct(ProductEntity product) {
this.product = product;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public Integer getStarsGiven() {
return starsGiven;
}
public void setStarsGiven(Integer starsGiven) {
this.starsGiven = starsGiven;
}
public Integer getTotalStars() {
return totalStars;
}
public void setTotalStars(Integer totalStars) {
this.totalStars = totalStars;
}
public Integer getTotalNumOfUsersWhoRated() {
return totalNumOfUsersWhoRated;
}
public void setTotalNumOfUsersWhoRated(Integer totalNumOfUsersWhoLiked) {
this.totalNumOfUsersWhoRated = totalNumOfUsersWhoLiked;
}
public BigDecimal getAverageStars() {
return averageStars;
}
public void setAverageStars(BigDecimal averageStars) {
this.averageStars = averageStars;
}
}
Api:
#CrossOrigin
#RestController
public class ProductApi {
private ProductService productService;
private ProductsRatedByUserService productsRatedByUserService;
#Autowired
public ProductApi(ProductService productService,ProductsRatedByUserService productsRatedByUserService){
this.productService=productService;
this.productsRatedByUserService=productsRatedByUserService;
}
#PutMapping("/product/rating/{pid}/{numOfStars}")
public ProductsRatedByUserResponseDto updateRating(#PathVariable Integer pid, #PathVariable Integer numOfStars, JwtAuthenticationToken jwtAuthenticationToken) throws ProductFoundByIdException {
FirebaseUserData firebaseUserData=new FirebaseUserData(jwtAuthenticationToken);
ProductsRatedByUserDetail productsRatedByUserDetail=productsRatedByUserService.updateProductRating(pid,numOfStars,firebaseUserData);
return new ProductsRatedByUserResponseDto(productsRatedByUserDetail);
}
}
RatingServiceImpl:
#Service
#Component
public class ProductsRatedByUserServiceImpl implements ProductsRatedByUserService {
public ProductsRatedByUserRepository productsRatedByUserRepository;
public ProductRepository productRepository;
public UserRepository userRepository;
#Autowired
public ProductsRatedByUserServiceImpl(ProductsRatedByUserRepository productsRatedByUserRepository,ProductRepository productRepository,UserRepository userRepository){
this.productsRatedByUserRepository=productsRatedByUserRepository;
this.productRepository=productRepository;
this.userRepository=userRepository;
}
#Override
public ProductsRatedByUserDetail updateProductRating(Integer pid, Integer numOfStars, FirebaseUserData firebaseUserData) throws ProductFoundByIdException {
if(!productRepository.existsById(pid)){
throw new ProductFoundByIdException();
}
UserEntity userEntity=userRepository.findUserEntityByEmail(firebaseUserData.getEmail());
ProductEntity productEntity =productRepository.findById(pid).orElse(null);
//check if the product has been rated by *any user*
//If no, we need to create an entity
if(!productsRatedByUserRepository.existsByProduct(productEntity)){
ProductsRatedByUserEntity productsRatedByUserEntity=new ProductsRatedByUserEntity(userEntity, productEntity, numOfStars);
ProductsRatedByUserEntity productsRatedByUserEntityReturned=productsRatedByUserRepository.save(productsRatedByUserEntity);
System.out.println("the product has been rated by *any user*");
return new ProductsRatedByUserDetail(productsRatedByUserEntityReturned);
}
//If yes, we update the entity from there
else {
//if the product has been rated by this very user
if (productsRatedByUserRepository.existsByUserAndProduct(userEntity, productEntity)) {
ProductsRatedByUserEntity productsRatedByUserEntity = productsRatedByUserRepository.findTopByUserAndProduct(userEntity, productEntity);
productsRatedByUserEntity.setTotalStars(productsRatedByUserEntity.getTotalStars() - productsRatedByUserEntity.getStarsGiven() + numOfStars);
productsRatedByUserEntity.setStarsGiven(numOfStars);
productsRatedByUserEntity.setAverageStars(BigDecimal.valueOf(productsRatedByUserEntity.getTotalStars()).divide(BigDecimal.valueOf(productsRatedByUserEntity.getTotalNumOfUsersWhoRated())));
ProductsRatedByUserEntity productsRatedByUserEntityReturned = productsRatedByUserRepository.save(productsRatedByUserEntity);
System.out.println("the product has been rated by this very user");
return new ProductsRatedByUserDetail(productsRatedByUserEntityReturned);
} else {
//The product has not been rated by this very user
ProductsRatedByUserEntity productsRatedByUserEntity = productsRatedByUserRepository.findTopByProduct(productEntity);
int newTotalNumOfStars = (productsRatedByUserEntity.getTotalStars() + numOfStars);
int newTotalNumberOfUsers = productsRatedByUserEntity.getTotalNumOfUsersWhoRated() + 1;
productsRatedByUserEntity.setUser(userEntity);
System.out.println("The product has not been rated by this very user");
return new ProductsRatedByUserDetail(productsRatedByUserRepository.save(new ProductsRatedByUserEntity(productEntity, userEntity, numOfStars, newTotalNumOfStars, newTotalNumberOfUsers, BigDecimal.valueOf(newTotalNumOfStars).divide(BigDecimal.valueOf(newTotalNumberOfUsers)))));
}
}
}
}
RatingServiceInterface:
public interface ProductsRatedByUserService {
ProductsRatedByUserDetail updateProductRating(Integer pid, Integer numOfStars, FirebaseUserData firebaseUserData) throws ProductFoundByIdException;
}
Repository:
public interface ProductsRatedByUserRepository extends CrudRepository<ProductsRatedByUserEntity,Integer> {
boolean existsByProduct(ProductEntity product);
ProductsRatedByUserEntity findTopByProduct(ProductEntity product);
boolean existsByUserAndProduct(UserEntity userEntity, ProductEntity product);
ProductsRatedByUserEntity findTopByUserAndProduct(UserEntity userEntity, ProductEntity product);
}
I will really appreciate anyone who can help me with this! I've been stuck for a whole day! I don't want to use the many-to-many annotation because it seems a bit messy. Thanks!
I have found the mistake. In my RatingEntity code, the getter and setter are erroneous. There's some typos there. It should be
public Integer getPruid() {
return pruid;
}
public void setPruid(Integer pruid) {
this.pruid = pruid;
}

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.

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

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;

How to delete child records using Spring Data JPA

I am having alot of issues trying to delete child records using JPA. Consider the mappings below. I am trying to delete all the state data in the jobs table. When it is removed it will cascade all deletes down the chain. Here is the chain:
Job -> State -> TaskState -> Step
When I try to remove state from job table it is set to NULL. However it is not cascaded down the chain. How would I go about achieving this?
Here is how I am deleting the data:
#Transactional
public void runJob(Long id) throws IOException, JAXBException {
Job job = jobRepository.findOne(id);
if(job.getState() != null){
State stateObj = stateRepository.findOne(job.getState().getId());
stateObj.setTasks(null);
stateRepository.delete(stateObj);
}
job.setState(null);
jobRepository.save(job);
}
Jobs:
#Entity
#Table(name = "jobs")
public class Job implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "description")
private String description;
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#OneToOne
private Image image;
#OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private State state;
#OneToMany
private List<Task> tasks;
#Column(name = "status")
#Enumerated(EnumType.STRING)
private JobStatusEnum status;
#ManyToMany
private List<Device> devices;
#OneToMany
private List<JobRun> runs;
#OneToMany
private List<Container> containers;
public Job() {
this.image = new Image();
this.status = JobStatusEnum.New;
this.devices = new ArrayList<>();
this.runs = new ArrayList<>();
this.containers = new ArrayList<>();
}
public Job(String name, String description, Date date, Image image, State state, List<Task> tasks, JobStatusEnum status, List<Device> devices, List<JobRun> runs, List<Container> containers) {
this.name = name;
this.description = description;
this.date = date;
this.image = image;
this.state = state;
this.tasks = tasks;
this.status = status;
this.devices = devices;
this.runs = runs;
this.containers = containers;
}
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 String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
public JobStatusEnum getStatus() {
return status;
}
public void setStatus(JobStatusEnum status) {
this.status = status;
}
public List<Device> getDevices() {
return devices;
}
public void setDevices(List<Device> devices) {
this.devices = devices;
}
public List<JobRun> getRuns() {
return runs;
}
public void setRuns(List<JobRun> runs) {
this.runs = runs;
}
public List<Container> getContainers() {
return containers;
}
public void setContainers(List<Container> containers) {
this.containers = containers;
}
}
State:
#Entity
#Table(name = "state")
public class State implements Serializable {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="name")
private String name;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<TaskState> tasks;
public State() {
tasks = new ArrayList<>();
}
public State(Long id, String name, List<TaskState> tasks) {
this.id = id;
this.name = name;
this.tasks = tasks;
}
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<TaskState> getTasks() {
return tasks;
}
public void setTasks(List<TaskState> tasks) {
this.tasks = tasks;
}
}
TaskState:
#Entity
#Table(name = "task_state")
public class TaskState implements Serializable {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "parent")
private Long parent;
#Column(name = "referenceid")
private Long referenceId;
#Column(name = "name")
private String name;
#Column(name = "status")
private TaskStatusEnum status;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Step> steps;
#Column(name = "maxAttempts")
private Integer maxAttempts;
#ManyToOne
#JsonIgnore
private State state;
public TaskState() {
status = TaskStatusEnum.New;
steps = new ArrayList<>();
maxAttempts = 5;
}
public TaskState(Long id, Long parent, Long referenceId, String name, TaskStatusEnum status, List<Step> steps, Integer maxAttempts) {
this();
this.id = id;
this.parent = parent;
this.referenceId = referenceId;
this.name = name;
this.status = status;
this.steps = steps;
this.maxAttempts = maxAttempts;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getParent() {
return parent;
}
public void setParent(Long parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TaskStatusEnum getStatus() {
return status;
}
public void setStatus(TaskStatusEnum status) {
this.status = status;
}
public List<Step> getSteps() {
return steps;
}
public void setSteps(List<Step> steps) {
this.steps = steps;
}
public Long getReferenceId() {
return referenceId;
}
public void setReferenceId(Long referenceId) {
this.referenceId = referenceId;
}
public Integer getMaxAttempts() {
return maxAttempts;
}
public void setMaxAttempts(Integer maxAttempts) {
this.maxAttempts = maxAttempts;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
Step:
#Entity
#Table(name = "step")
public class Step implements Serializable {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "groupname")
private String group;
#Column(name = "route")
private String route;
#Column(name = "celerytask")
private String celeryTask;
#Column(name = "postbackqueuename")
private String postBackQueueName;
#Column(name = "postbackerrorqueuename")
private String postBackErrorQueueName;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private TaskStatusEnum status;
#ElementCollection
private List<String> arguements;
#Column(name="runningTaskId")
private Long runningTaskId;
#Column(name="result")
private String result;
#Column(name="attempt")
private Integer attempt;
#JsonIgnore
#ManyToOne
private TaskState task;
public Step() {
arguements = new ArrayList<>();
status = TaskStatusEnum.New;
attempt = 0;
}
public Step(String name, String group, String route, String celeryTask, String postBackQueueName, String postBackErrorQueueName, TaskStatusEnum status, List<String> arguements, Long runningTaskId) {
this();
this.name = name;
this.group = group;
this.route = route;
this.celeryTask = celeryTask;
this.postBackQueueName = postBackQueueName;
this.postBackErrorQueueName = postBackErrorQueueName;
this.status = status;
this.arguements = arguements;
this.runningTaskId = runningTaskId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getRoute() {
return route;
}
public void setRoute(String route) {
this.route = route;
}
public String getCeleryTask() {
return celeryTask;
}
public void setCeleryTask(String celeryTask) {
this.celeryTask = celeryTask;
}
public String getPostBackQueueName() {
return postBackQueueName;
}
public void setPostBackQueueName(String postBackQueueName) {
this.postBackQueueName = postBackQueueName;
}
public String getPostBackErrorQueueName() {
return postBackErrorQueueName;
}
public void setPostBackErrorQueueName(String postBackErrorQueueName) {
this.postBackErrorQueueName = postBackErrorQueueName;
}
public List<String> getArguements() {
return arguements;
}
public void setArguements(List<String> arguements) {
this.arguements = arguements;
}
public TaskStatusEnum getStatus() {
return status;
}
public void setStatus(TaskStatusEnum status) {
this.status = status;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public Integer getAttempt() {
return attempt;
}
public void setAttempt(Integer attempt) {
this.attempt = attempt;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getRunningTaskId() {
return runningTaskId;
}
public void setRunningTaskId(Long runningTaskId) {
this.runningTaskId = runningTaskId;
}
public TaskState getTask() {
return task;
}
public void setTask(TaskState task) {
this.task = task;
}
}
It's not cascading because of stateObj.setTasks(null);.
You're breaking the link between the State and its Tasks so when you're deleting the State, the delete doesn't cascade on anything.

How Hibernate to query three tables in a time?

I have three tables :
1. org,
2. product_info
3. service_info.
And, table product_info is mapping table service_info ManyToMany,
means,many products mapping many services.
While,table org is mapping table product_info OneToMany,
means,one org have many products.
When I initialize my web
I want to view the org table's column. How to do ?
Under classes are the persistent classes for three tables.
ProductService class:
`
#Entity
#Table(name="product_service")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class ProductService implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private ServiceInfo serviceInfo;//this is the service table
private String parammapping;
private ProductInfo productInfo;//this is the product table
// Constructors
/** default constructor */
public ProductService() {
}
/** minimal constructor */
public ProductService(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="SERVICEID")
public ServiceInfo getServiceInfo() {
return this.serviceInfo;
}
public void setServiceInfo(ServiceInfo serviceInfo) {
this.serviceInfo = serviceInfo;
}
#Column(name="PARAMMAPPING", length=1000)
public String getParammapping() {
return parammapping;
}
public void setParammapping(String parammapping) {
this.parammapping = parammapping;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="PRODUCTID")
public ProductInfo getProductInfo() {
return this.productInfo;
}
public void setProductInfo(ProductInfo productInfo) {
this.productInfo = productInfo;
}
}`
baseOrg class:
#Entity
#Table(name="base_org")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class BaseOrg implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String code;
private String name;
private List<BaseRuleEngineLog> serviceUsedLogs = new ArrayList<BaseRuleEngineLog>(0);
private List<ProductInfo> productInfos = new ArrayList<ProductInfo>(0);
private List<BaseCreditQuery> baseCreditQueries = new ArrayList<BaseCreditQuery>(0);
// Constructors
/** default constructor */
public BaseOrg() {
}
/** minimal constructor */
public BaseOrg(String id) {
this.id = id;
}
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name="CODE", length=50)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name="NAME", length=200)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<BaseRuleEngineLog> getServiceUsedLogs() {
return this.serviceUsedLogs;
}
public void setServiceUsedLogs(List<BaseRuleEngineLog> serviceUsedLogs) {
this.serviceUsedLogs = serviceUsedLogs;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<ProductInfo> getProductInfos() {
return this.productInfos;
}
public void setProductInfos(List<ProductInfo> productInfos) {
this.productInfos = productInfos;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="baseOrg")
public List<BaseCreditQuery> getBaseCreditQueries() {
return this.baseCreditQueries;
}
public void setBaseCreditQueries(List<BaseCreditQuery> baseCreditQueries) {
this.baseCreditQueries = baseCreditQueries;
}
}
productInfo class:
#Entity
#Table(name="product_info")
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class ProductInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private BaseOrg baseOrg;//baseOrg table
private String code;
private String name;
private String orgcode;
private List<ProductService> productServices = new ArrayList<ProductService>(0);
// Constructors
/** default constructor */
public ProductInfo() {
}
/** minimal constructor */
public ProductInfo(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="ORGID")
public BaseOrg getBaseOrg() {
return this.baseOrg;
}
public void setBaseOrg(BaseOrg baseOrg) {
this.baseOrg = baseOrg;
}
#Column(name="CODE", length=100)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name="NAME", length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="ORGCODE", length=100)
public String getOrgcode() {
return this.orgcode;
}
public void setOrgcode(String orgcode) {
this.orgcode = orgcode;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="productInfo")
public List<ProductService> getProductServices() {
return this.productServices;
}
public void setProductServices(List<ProductService> productServices) {
this.productServices = productServices;
}
}
serviceInfo class
#Entity
#Table(name="service_info")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class ServiceInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String code;
private List<ProductService> productServices = new ArrayList<ProductService>(0);
// Constructors
/** default constructor */
public ServiceInfo() {
}
/** minimal constructor */
public ServiceInfo(String id) {
this.id = id;
}
// Property accessors
#Id
#Column(name="ID", unique=true, nullable=false, length=50)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name="NAME", length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="CODE", length=100)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="serviceInfo")
public List<ProductService> getProductServices() {
return this.productServices;
}
public void setProductServices(List<ProductService> productServices) {
this.productServices = productServices;
}
}
product_service table
Thank you for forgiving my poor English,this is my first time questioning on Stack Overflow.
OK,I resolve it.
i found its so sample,lol.
Because,most criteria have been packaged.At the first time ,I want to use the HQL to resolve it,but in vain.I just add this sentences,and getted it.
enter image description here

Categories

Resources