My problem is when I try to make a customized query, I want to use crudrepository or jpa for the repository and make my own methods to do the following operations on the database, but I can't succeed in any way...
this is CartRepository
package com.example.registrationlogindemo.repository;
import com.example.registrationlogindemo.model.Cart;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface CartRepository extends CrudRepository<Cart,Long> {
@Query(name = "INSERT INTO cart VALUES (:productID,:userID)",nativeQuery = true)
List<Cart> save(@Param("productID") Long productId, @Param("userID") Long userID);
@Query(name = "SELECT * FROM cart WHERE user_id = ?2",nativeQuery = true)
List<Cart>showAll(Long productID, Long userID);
}
this is Cart
package com.example.registrationlogindemo.model;
import jakarta.persistence.*;
import lombok.*;
@Data
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "cart")
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
and this is my controller
@Controller
public class CartController {
private static SessionFactory factory;
Long saveId;
@Autowired
ProductRepository productRepository;
@Autowired
UserRepository userRepository;
CartRepository cartRepository;
@GetMapping("/shoppingCart")
@ResponseBody
public String showCart(Model model, Principal principal){
String nume = principal.getName();
cartRepository.save(saveId,userRepository.AiciVoiAveaId(nume));
Optional<Product> product = productRepository.findById(saveId);
model.addAttribute("product", product.get());
return "shoppingCart";
}
@PostMapping("/shoppingCart/{id}")
public String shoppingCart(@PathVariable Long id){
saveId = id;
return "redirect:/shoppingCart";
}
}
Error
2023-01-05T15:39:16.146 02:00 WARN 16652 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cartRepository' defined in com.example.registrationlogindemo.repository.CartRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.List com.example.registrationlogindemo.repository.CartRepository.save(java.lang.Long,java.lang.Long); Reason: Failed to create query for method public abstract java.util.List com.example.registrationlogindemo.repository.CartRepository.save(java.lang.Long,java.lang.Long); No property 'save' found for type 'Cart'
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cartRepository' defined in com.example.registrationlogindemo.repository.CartRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.List com.example.registrationlogindemo.repository.CartRepository.save(java.lang.Long,java.lang.Long); Reason: Failed to create query for method public abstract java.util.List com.example.registrationlogindemo.repository.CartRepository.save(java.lang.Long,java.lang.Long); No property 'save' found for type 'Cart'
can someone help me ?
Hi, I have a problem too, I try to create a specific query for several actions and I get errors and I don't understand why...
CodePudding user response:
Salut,
You can try with JpaRepository:
@Repository
public interface CartRepository extends JpaRepository<Cart, Long> {
@Query("FROM Cart WHERE user.id = :userID")
List<Cart> findAllByUserId(Long userID);
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "cart")
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_user", nullable = false)
private User user;
}
And then you can use the repository like so:
Cart cartToBeSaved = new Cart(userId);
cartRepository.save(cartToBeSaved); //cart id is auto-generated
Also, I would avoid declaring a global Long saveId;
. It has no useful purpose and can lead to more serious issues when multiple users are accessing these endpoints.
I would also move some logic in a service class and I would encapsulate the repositories.
For example:
@Controller
@RequiredArgsConstructor
public class CartController {
private final CartService cartService;
@GetMapping("/shoppingCart")
public String showCart(Model model, Principal principal) {
Product product = cartService.saveProduct(...);
model.addAttribute("product", product.get());
return "shoppingCart";
}
@PostMapping("/shoppingCart/{id}")
public String shoppingCart(@PathVariable Long id){
//something here
}
}
@Service
@RequiredArgsConstructor
public class CartService {
private final ProductRepository productRepository;
private final UserRepository userRepository;
private final CartRepository cartRepository;
public Product saveProduct(...) {
//some business logic here
}
}
CodePudding user response:
Your save()
method contains a faulty sql command. The INSERT
command for SQL does not work this way. I don't know exactly the qualities of your Cart
object, but it needs to look like the following way.
@Modifying
@Query(name = "INSERT INTO cart (productId, userId) VALUES (:productID,:userID)",nativeQuery = true)
List<Cart> save(@Param("productID") Long productId, @Param("userID") Long userID);
A SQL INSERT
command must contain the column names of the corresponding table.
I also recommend using @Modifying
annotation for commands such as INSERT
, UPDATE
, DELETE
. You can find detailed information about @Modifying
anatotion here.