好的开始: 我在春天做药房项目。我正在使用Eclipse和Database PostgreSQL。
在数据库中我有表名:OrderItem,CustomerOrder,Product和Register(这是带有关于用户的传递和信息的类)。
好的,我想删除给定ID的CustomerOrder。
co.deleteCustomerOrder(co.getCustomerOrder(id));
如果我这样做了,我有这样的错误:
详细信息:Key(orderid)=(1421007984736)在表格中调用" orderItem" 错误:修改或删除表"客户端"违反外键" fk60163f61b0099af4"表" orderitem"
所以我首先添加了这个
cos.deleteOrderItem(cos.getOrderItem(id))
然后
co.deleteCustomerOrder(co.getCustomerOrder(id));
现在我有这样的错误:
HTTP状态500 - 请求处理失败;嵌套异常是java.lang.IllegalArgumentException:尝试使用null实体创建删除事件
也许某些实体类存在问题:注册或其他。当我用PgAdminIII orderItem删除的方式当然我没有得到第一个错误,我可以完成这行代码
co.deleteCustomerOrder(co.getCustomerOrder(id));
正常。
****如何解决第二个错误?我不想使用PgAdmin xD ****
我的一些代码。
package app.Spring.domain;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "CustomerOrder")
public class CustomerOrder {
@Id
@Column(name = "orderID")
private long orderID;
@ManyToOne(cascade = { CascadeType.MERGE })
private Register register;
@Column(name = "status")
private String status;
@Column(name = "totalCost")
private float totalCost;
@Column(name = "orderDate")
private Date orderDate;
public CustomerOrder() {
}
public CustomerOrder(long orderID, Register register, String status,
float totalCost, Date orderDate) {
this.orderID = orderID;
this.register = register;
this.status = status;
this.totalCost = totalCost;
this.orderDate = orderDate;
}
public long getOrderID() {
return orderID;
}
public void setOrderID(long orderID) {
this.orderID = orderID;
}
public Register getRegister() {
return register;
}
public void setRegister(Register register) {
this.register = register;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public float getTotalCost() {
return totalCost;
}
public void setTotalCost(float totalCost) {
this.totalCost = totalCost;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
package app.Spring.domain;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "OrderItem")
public class OrderItem {
@Id
@Column(name = "itemID")
private long itemID;
@ManyToOne(cascade = { CascadeType.MERGE })
private Product product;
@ManyToOne(cascade = { CascadeType.MERGE })
private CustomerOrder customerOrder;
@Column(name = "quantity")
private int quantity;
public OrderItem() {
}
public OrderItem(long itemID, Product product, CustomerOrder customerOrder,
int quantity) {
this.itemID = itemID;
this.product = product;
this.customerOrder = customerOrder;
this.quantity = quantity;
}
public long getItemID() {
return itemID;
}
public void setItemID(long itemID) {
this.itemID = itemID;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public CustomerOrder getCustomerOrder() {
return customerOrder;
}
public void setCustomerOrder(CustomerOrder customerOrder) {
this.customerOrder = customerOrder;
}
public long getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
控制器
@Controller
@RequestMapping("/admin/users")
public class AdminController {
@Autowired
LocalValidatorFactoryBean validator;
@Autowired
RegisterService reg;
@Autowired
CustomerOrderService co;
@Autowired
OrderItemService cos;
@RequestMapping("/removecustomer/{id}")
public String removeCustomerOrderById(@PathVariable Long id) {
System.out.println("remove customerOrderID "+id);
cos.deleteOrderItem(cos.getOrderItem(id));
co.deleteCustomerOrder(co.getCustomerOrder(id));
return "redirect:/";
}
}
CustomerOrderService
public class CustomerOrderImpl implements CustomerOrderService{
protected final Logger log = LoggerFactory.getLogger(getClass());
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public CustomerOrder getCustomerOrder(Long id) {
return (CustomerOrder)sessionFactory.getCurrentSession().get(CustomerOrder.class.getName(), id);
}
public void deleteCustomerOrder(CustomerOrder v) {
sessionFactory.getCurrentSession().delete(v);
sessionFactory.getCurrentSession().flush();
}
}
OrderService
public class OrderItemImpl implements OrderItemService {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public OrderItem getOrderItem(Long id) {
return (OrderItem)sessionFactory.getCurrentSession().get(OrderItem.class.getName(), id);
}
public void deleteOrderItem(OrderItem v) {
sessionFactory.getCurrentSession().delete(v);
sessionFactory.getCurrentSession().flush();
}
}
答案 0 :(得分:1)
cos.deleteOrderItem(cos.getOrderItem(id));
co.deleteCustomerOrder(co.getCustomerOrder(id));
表中的每个记录(行)都有一个键。您使用相同的密钥删除两个不同表中的项目。
除非它们恰好处于一对一的关系中,否则记录的ID不会反映这种关系。在这种情况下,您尝试使用未记录的密钥删除订单商品。
坦率地说:
您想要删除customerOrder 16;
您无法删除customerOrder 16;因为它有orderItems 4& 5由于外键而与之相关。
您正在尝试删除订单商品16;哪个不存在(第二个错误)。
正确的解决方案是:
将customerOrder和orderItems之间的关系设置为级联(cascade = {CascadeType.DELETE, CascadeType.MERGE})
在删除customerOrder
之前,找到相关的orderItems
并删除它们(再次,不同元素的关键字将不相关)。
如果您在理解密钥,外键和级联的概念时遇到问题,首先应该了解SQL的工作原理。
答案 1 :(得分:0)
问题解决了:)
更改删除和更改查找相关orderItem的代码的方法。为了你,我应该学习更多SQL.This CascadeType.Remove不需要。
public void deleteOrderItem2(OrderItem orderItem) throws Exception {
Session session=null;
Transaction tx=null;
try {
session = sessionFactory.openSession();
tx=session.beginTransaction();
orderItem = (OrderItem) session.merge(orderItem);
session.delete(orderItem);
session.flush();
tx.commit();
} catch (PersistenceException pe) {
tx.rollback();
throw pe;
} finally {
session.close();
}
}