我正在开发一个电子商务后端在Spring启动。每次我为同一个User
创建两个以上的订单
时,我都会得到以下错误:org.hibernate.HibernateExc0019:找到了多个具有给定标识符的行: 40,用于类:com.ptoject.demo.entities.用户
.要创建一个订单,我首先创建一个付款,然后创建由付款生成的订单,所以问题可能也出在付款的创建上。
订单
实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name = "order", schema = "purchase")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "order_time")
private Date orderTime;
@OneToMany(mappedBy = "order", cascade = CascadeType.MERGE)
private List<ProductInOrder> productsInOrder;
@ManyToOne
@JoinColumn(name = "buyer")
private User buyer;
@OneToOne
@JoinColumn(name = "payment_id")
@JsonIgnore
private Payment payment;
@OneToOne
@JoinColumn(name = "cart_id")
private Cart cart;
}
用户
实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name="user", schema = "purchase")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@Column(name = "code", nullable = true, length = 70)
private String code;
@Basic
@Column(name = "first_name", nullable = true, length = 50)
private String firstName;
@Basic
@Column(name = "last_name", nullable = true, length = 50)
private String lastName;
@Basic
@Column(name = "telephone", nullable = true, length = 20)
private String telephone;
@Basic
@Column(name = "email", nullable = true, length = 90)
private String email;
@Basic
@Column(name = "password", nullable = true, length = 90)
private String password;
@Basic
@Column(name = "address", nullable = true, length = 150)
private String address;
@OneToMany(mappedBy = "buyer", cascade = CascadeType.MERGE)
@JsonIgnore
private List<Order> orders;
@OneToMany(mappedBy = "user", cascade = CascadeType.MERGE)
@JsonIgnore
private List<QuestionForUser> questionsForUser;
@OneToOne(mappedBy = "buyer")
@JsonIgnore
private Cart cart;
@OneToMany(mappedBy = "user", cascade = CascadeType.MERGE)
@JsonIgnore
private List<Answer> answer;
}
支付
实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name = "payment", schema = "purchase")
public class Payment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@Column(name = "owner_name", nullable = true, length = 70)
private String ownerName;
@Basic
@Column(name = "owner_last_name", nullable = true, length = 70)
private String ownerLastName;
@Basic
@Column(name = "card_number", nullable = true, length = 16)
//il numero di una carta PayPal è di 16 cifre
private String cardNumber;
@Basic
@Temporal(TemporalType.DATE)
@Column(name = "expiration", nullable = true)
private Date expiration;
@Basic
@Column(name = "cvv", nullable = true, length = 3)
private String cvv;
@Basic
@Column(name = "total", nullable = true)
private float total;
@OneToOne(mappedBy = "payment")
private Order order;
}
OrderService
:
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private ProductInOrderRepository productInOrderRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private CartRepository cartRepository;
@Autowired
private PaymentRepository paymentRepository;
@Autowired
private EntityManager entityManager;
@Transactional(readOnly = false)
public Order createOrder (int paymentId, int userId, int cartId) {
User user = userRepository.findById(userId);
Payment payment = paymentRepository.findById(paymentId);
Cart c = cartRepository.findById(cartId);
List<ProductInOrder> productsInOrder=new LinkedList<>();
List<ProductInCart> productsInCart=c.getProductsInCart();
Order o = new Order();
o.setPayment(payment);
o.setCart(c);
o.setBuyer(user);
for(ProductInCart productInCart: productsInCart){
ProductInOrder productInOrder = new ProductInOrder();
productInOrder.setProduct(productInCart.getProduct());
productInOrder.setOrder(o);
productInOrder.setQuantity(productInCart.getQuantity());
productInOrderRepository.save(productInOrder);
productsInOrder.add(productInOrder);
}
o.setProductsInOrder(productsInOrder);
payment.setOrder(o);
Order justAdded = orderRepository.save(o);
entityManager.refresh(justAdded);
entityManager.refresh(o);
return justAdded;
}
OrderController
:
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/create")
@ResponseStatus(code = HttpStatus.OK)
public ResponseEntity<Order> createOrder (@RequestParam(required = false) int paymentId,
@RequestParam(required = false) int buyerId,
@RequestParam(required = false) int cartId){
return new ResponseEntity<>(orderService.createOrder(paymentId, buyerId, cartId), HttpStatus.OK);
}
支付服务:
@Service
public class PaymentService {
@Autowired
private PaymentRepository paymentRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
@Autowired
private EntityManager entityManager;
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public Payment addPayment(Payment p) throws PaymentAlreadyExistsException, IncorrectCardNumberException, IncorrectCvvException{//
if(paymentRepository.existsByCardNumber(p.getCardNumber())){
throw new PaymentAlreadyExistsException();
}
if(p.getCardNumber().length()!=16){
throw new IncorrectCardNumberException();
}
if(p.getCvv().length()!=3)
{
throw new IncorrectCvvException();
}
return paymentRepository.save(p);
}
###########################################################################################
@RestController
@RequestMapping("/payments")
public class PaymentController {
@Autowired
private PaymentService paymentService;
@PostMapping("/createPayment")//funziona
public ResponseEntity<Payment> create(@RequestBody @Valid Payment payment){
System.out.print("Sono in paymentController.");
try {
Payment added=paymentService.addPayment(payment);
return new ResponseEntity<>(added, HttpStatus.OK);
} catch (PaymentAlreadyExistsException e) {
return new ResponseEntity(new ResponseMessage("Payment already exists!"), HttpStatus.BAD_REQUEST);
} catch (IncorrectCardNumberException e) {
return new ResponseEntity(new ResponseMessage("Incorrect card number!"), HttpStatus.BAD_REQUEST);
} catch (IncorrectCvvException e) {
return new ResponseEntity(new ResponseMessage("Incorrect CVV"), HttpStatus.BAD_REQUEST);
}
}
异常堆栈跟踪:
产品ontroller.add产品车:
@PostMapping("/addProduct")
@ResponseStatus(code = HttpStatus.OK)
public ResponseEntity<Product> addProductToCart(@RequestParam(required = false) int productId,
@RequestParam(required = false) int userId,
@RequestParam(required = false) int quantity){
try {
return new ResponseEntity<>(productService.addToCart(productId, userId, quantity), HttpStatus.OK);
} catch (ProductUnavailableException e) {
return new ResponseEntity(new ResponseMessage("The quantity of product: "+e.getProduct().getName()+" is unavailable!"), HttpStatus.BAD_REQUEST);
}
}
产品服务。addToCart:
@Transactional(readOnly = false, rollbackForClassName = {ProductUnavailableException})
public Product addToCart (int productId, int userId, int quantity) throws ProductUnavailableException {
User user = userRepository.findById(userId);
Product product = productRepository.findById(productId);
Cart c = user.getCart();
List<ProductInCart> pc = c.getProductsInCart();
ProductInCart p = new ProductInCart();
p.setProduct(product);
p.setCart(c);
p.setQuantity(quantity);
ProductInCart justAdded = productInCartRepository.save(p);
Product pr = justAdded.getProduct();
int newQuantity = pr.getQuantity() - p.getQuantity();
if (newQuantity < 0) {
p.setCart(null);
productInCartRepository.delete(p);
throw new ProductUnavailableException(pr);
}
product.setQuantity(newQuantity);
float newTotal=c.getTotal()+pr.getPrice();
c.setTotal(newTotal);
return pr;
}
表购物车
:
购物车
实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name = "cart", schema = "purchase")
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@Column(name = "total", nullable = true)
private float total;
@OneToMany(mappedBy = "cart", cascade = CascadeType.MERGE)
private List<ProductInCart> productsInCart;
@OneToOne
@JoinColumn(name = "user_id")
private User buyer;
@OneToOne(mappedBy = "cart")
@JsonIgnore
private Order order;
}
用户
表格:
我解决了我的问题,我会发布对我有效的解决方案,以防有人,有同样的问题,正在寻找解决方案。我在购物车
和用户
之间有1:1的关系,用户
和订单
之间有1:n的关系,购物车
和订单
之间有1:1的关系。这可能会在关系之间创建一个类似循环的东西,因此我通过编辑OrderService来删除
按以下方式:Cart
和Order
an之间的关系,从而解决了我的问题。createOrder(paymentId、userId、cartId)
@Transactional(readOnly = false)
public Order createOrder(int userId, int paymentId) {
User user = userRepository.findById(userId);
Payment payment=paymentRepository.findById(paymentId);
Order o = new Order();
o.setBuyer(user);
o.setTotal(payment.getTotal());
o.setPayment(payment);
List<ProductInOrder> po=new LinkedList<>();
List<ProductInCart> pc=user.getCart().getProductsInCart();
for(ProductInCart productInCart: pc){
ProductInOrder productInOrder=new ProductInOrder();
productInOrder.setProduct(productInCart.getProduct());
productInOrder.setQuantity(productInCart.getQuantity());
productInOrder.setOrder(o);
productInOrderRepository.save(productInOrder);
po.add(productInOrder);
}
o.setProductsInOrder(po);
List<Order> ordersForUser = user.getOrders();
ordersForUser.add(o);
user.setOrders(ordersForUser);
payment.setOrder(o);
Order justAdded = orderRepository.save(o);
entityManager.refresh(justAdded);
entityManager.refresh(o);
entityManager.refresh(user);
return justAdded;
}
订单管理员。createOrder:
@PostMapping("/create")
@ResponseStatus(code = HttpStatus.OK)
public ResponseEntity<Order> createOrder (@RequestParam(required = false) int buyerId,
@RequestParam(required = false) int paymentId){
return new ResponseEntity<>(orderService.createOrder(buyerId, paymentId), HttpStatus.OK);
}
订单实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name = "order", schema = "purchase")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "order_time")
private Date orderTime;
@OneToMany(mappedBy = "order", cascade = CascadeType.MERGE)
private List<ProductInOrder> productsInOrder;
@ManyToOne
@JoinColumn(name = "buyer")
private User buyer;
@OneToOne
@JoinColumn(name = "payment_id")
@JsonIgnore
private Payment payment;
@Basic
@Column(name = "total", nullable = true)
private float total;
}
购物车实体:
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Entity
@Table(name = "cart", schema = "purchase")
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
@Basic
@Column(name = "total", nullable = true)
private float total;
@OneToMany(mappedBy = "cart", cascade = CascadeType.MERGE)
private List<ProductInCart> productsInCart;
@OneToOne
@JoinColumn(name = "user_id")
private User buyer;
}
User user = userRepository.findById(userId);
当您的JPA方法需要一个结果时,在这种情况下,您希望返回的是用户
,并且有更多记录要返回,Hibernate将抛出一个异常,更具体地说是您收到的异常。
解决方案
如果您定义的某个自定义JPA方法出现此错误,则应在存储库中定义此方法,以不返回单个结果,而是返回一个结果列表(如果业务方面接受)。因此,在某些方法中,您应该修改定义以返回列表,而不是返回
User
但在您的情况下,因为它是Spring提供的默认方法,
findById(userId)
,并且考虑到它是按主键搜索的,所以上述方法不应该是解决方案。您的数据库架构应该是错误的,并且此表中的记录也应该是错误的。
尝试手动更正数据库中的表
User
,使列id
成为primary key
,并尝试删除存在的相同id
的多条记录。当您清理并更正数据库中的表时,此问题不应再出现。
在您的代码中,我看不出有任何理由使用
entityManager.refresh
。这可能会产生一些问题。此外,Transactional
将无法与您在代码中抛出的检查异常一起工作。检查下面的代码并应用它。清理DB中的记录,并使用此代码重试,看看是否消除了问题。
@Transactional(readOnly = false, rollbackForClassName = {ProductUnavailableException})
public Product addToCart (int productId, int userId, int quantity) throws ProductUnavailableException {
User user = userRepository.findById(userId);
Product product = productRepository.findById(productId);
Cart c = user.getCart();
List<ProductInCart> pc = c.getProductsInCart();
ProductInCart p = new ProductInCart();
p.setProduct(product);
p.setCart(c);
p.setQuantity(quantity);
ProductInCart justAdded = productInCartRepository.save(p);
int newQuantity = product.getQuantity() - p.getQuantity();
if (newQuantity < 0) {
p.setCart(null);
productInCartRepository.delete(p);
throw new ProductUnavailableException(pr);
}
product.setQuantity(newQuantity);
float newTotal=c.getTotal()+product.getPrice();
c.setTotal(newTotal);
return product;
}
组织。冬眠HibernateeException:找到了多个具有给定标识符的行:578,用于类:com。冬眠查询表演坚持不懈模型百货商店 数据库没有标识符为578的重复存储行。使用SQL对其进行了检查: 它返回0条记录。 关于一、二的其他问题指出,问题可能与OneToOne映射本身有关。商店和员工实体具有OneToOne关系,我的映射如下: 工作人员: 商店: 如何修复它? 更新: 当查询被修改为
我有两张桌子,两张桌子之间有一对一的关系。 A表中的 用户表: 我称之为询问 和错误日志: 当我在数据库中有一个带有这个Bname的条目时,我得到了这个执行选项。 有人有什么想法吗 干杯
我有两个实体,由单向连接OneTo很多: 当我试图用汽车创造我的司机时,像这样 ENVERS创建: 驱动程序表中包含新驱动程序数据的行,//例如,ID=1 包含新车数据的CAR表中的一行,//例如,ID=3 修订实体表中的一行,//例如,ID=8 驱动程序中的一行\u AUD: 一辆车有两排: 所以当我试图修改ID=1的驱动程序时 我得到了HibernateException,因为有两行具有相同的
我有一个实体A,它与TempA实体有关系,如下所示: 然后在doInHibernate我称之为 然后我收到了错误。TempA是一个共享表,因此其他服务可以实际插入该表。我需要的是防止冬眠者称之为TempA。我能够阻止它与A进行左连接,但是,它仍然会导致这个错误。
下面是我的代码的模型、服务实现和错误跟踪。 模型类: 我的服务: 我的堆栈跟踪: 我在这行中得到了HibernateException,尽管我的表现在有两行id相同。 请任何人帮助我的错误。我的代码中可能有什么错误。
我在我的spring boot应用程序中出现了这个错误。当我想调用这个存储库时,我遇到了这个错误 这是我的存储库: 这就是我称之为此方法的地方: 如何检查方法返回的结果?我调试了我的代码,但在断点它只是返回这个错误。 谢谢你的帮助。