Spring多对多关系的问题

时间:2019-12-18 09:36:55

标签: java spring hibernate spring-boot maven

我的申请有问题。目前,我的车辆和订单表具有多对多关系。问题是当我从前端获得输入时,order_vehicle的登台表不会更新。我不确定在SpringBoot中有多少个工作,并且有我添加的注释,例如@JsonIgnore,如果不添加,我将具有无限递归JSON。我一直在努力解决我的问题,但是没有解决。我正在使用Hibernate 5.2,并从数据库中进行反向工程。

Order.java

package com.jdm.entity;
// Generated 11-Dec-2019 10:05:44 by Hibernate Tools 5.2.12.Final
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;

/**
 * Order generated by hbm2java
 */
@Entity
@Table(name = "order", catalog = "crud")
public class Order implements java.io.Serializable {

    private OrderId id;
    private Date date;
    private Float total;

    @JsonIgnore
    private Customer customer;
    @JsonIgnore
    private Employee employee;
    //@JsonIgnore
    private Set<Vehicle> vehicles = new HashSet<Vehicle>(0);

    public Order() {
    }

    public Order(OrderId id, Customer customer, Employee employee) {
        this.id = id;
        this.customer = customer;
        this.employee = employee;
    }

    public Order(OrderId id, Customer customer, Employee employee, Date date, Float total, Set<Vehicle> vehicles) {
        this.id = id;
        this.customer = customer;
        this.employee = employee;
        this.date = date;
        this.total = total;
        this.vehicles = vehicles;
    }

    @EmbeddedId

    @AttributeOverrides({ @AttributeOverride(name = "OId", column = @Column(name = "o_id", nullable = false)),
            @AttributeOverride(name = "customerCustId", column = @Column(name = "customer_cust_id", nullable = false)),
            @AttributeOverride(name = "employeeEmpId", column = @Column(name = "employee_emp_id", nullable = false)) })
    public OrderId getId() {
        return this.id;
    }

    public void setId(OrderId id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_cust_id", nullable = false, insertable = false, updatable = false)
    public Customer getCustomer() {
        return this.customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_emp_id", nullable = false, insertable = false, updatable = false)
    public Employee getEmployee() {
        return this.employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "date", length = 10)
    public Date getDate() {
        return this.date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Column(name = "total", precision = 12, scale = 0)
    public Float getTotal() {
        return this.total;
    }

    public void setTotal(Float total) {
        this.total = total;
    }

    @ManyToMany(fetch = FetchType.LAZY,cascade = {CascadeType.ALL})
//  @JsonBackReference
    @JoinTable(name = "order_has_vehicle", catalog = "crud", joinColumns = {
            @JoinColumn(name = "order_o_id", nullable = false, updatable = false),
            @JoinColumn(name = "order_customer_cust_id", nullable = false, updatable = false),
            @JoinColumn(name = "order_employee_emp_id", nullable = false, updatable = false) }, inverseJoinColumns = {
                    @JoinColumn(name = "vehicle_v_id", nullable = false, updatable = false) })
    public Set<Vehicle> getVehicles() {
        return this.vehicles;
    }

    public void setVehicles(Set<Vehicle> vehicles) {
        this.vehicles = vehicles;
    }

}

OrderId.java

package com.jdm.entity;
// Generated 16-Dec-2019 23:11:42 by Hibernate Tools 5.2.12.Final

import javax.persistence.Column;
import javax.persistence.Embeddable;

/**
 * OrderId generated by hbm2java
 */
@Embeddable
public class OrderId implements java.io.Serializable {

    private int OId;
    private int customerCustId;
    private int employeeEmpId;

    public OrderId() {
    }

    public OrderId(int OId, int customerCustId, int employeeEmpId) {
        this.OId = OId;
        this.customerCustId = customerCustId;
        this.employeeEmpId = employeeEmpId;
    }

    @Column(name = "o_id", nullable = false)
    public int getOId() {
        return this.OId;
    }

    public void setOId(int OId) {
        this.OId = OId;
    }

    @Column(name = "customer_cust_id", nullable = false)
    public int getCustomerCustId() {
        return this.customerCustId;
    }

    public void setCustomerCustId(int customerCustId) {
        this.customerCustId = customerCustId;
    }

    @Column(name = "employee_emp_id", nullable = false)
    public int getEmployeeEmpId() {
        return this.employeeEmpId;
    }

    public void setEmployeeEmpId(int employeeEmpId) {
        this.employeeEmpId = employeeEmpId;
    }

    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof OrderId))
            return false;
        OrderId castOther = (OrderId) other;

        return (this.getOId() == castOther.getOId()) && (this.getCustomerCustId() == castOther.getCustomerCustId())
                && (this.getEmployeeEmpId() == castOther.getEmployeeEmpId());
    }

    public int hashCode() {
        int result = 17;

        result = 37 * result + this.getOId();
        result = 37 * result + this.getCustomerCustId();
        result = 37 * result + this.getEmployeeEmpId();
        return result;
    }

}

Vehicle.java

package com.jdm.entity;
// Generated 11-Dec-2019 10:05:44 by Hibernate Tools 5.2.12.Final

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 * Vehicle generated by hbm2java
 */
@Entity
@Table(name = "vehicle", catalog = "crud")
public class Vehicle implements java.io.Serializable {

    private Integer VId;
    private String VManufacturer;
    private String VModel;
    private Integer VYear;
    private String VCategory;
    private String VTransmission;
    private Integer VMilleage;
    private String VPlate;
    private String VColor;
    private Float VPrice;


    private Set<Order> orders = new HashSet<Order>(0);

    public Vehicle() {
    }

    public Vehicle(String VManufacturer, String VModel, Integer VYear, String VCategory, String VTransmission,
            Integer VMilleage, String VPlate, String VColor, Float VPrice, Set<Order> orders) {
        this.VManufacturer = VManufacturer;
        this.VModel = VModel;
        this.VYear = VYear;
        this.VCategory = VCategory;
        this.VTransmission = VTransmission;
        this.VMilleage = VMilleage;
        this.VPlate = VPlate;
        this.VColor = VColor;
        this.VPrice = VPrice;
        this.orders = orders;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)

    @Column(name = "v_id", unique = true, nullable = false)
    public Integer getVId() {
        return this.VId;
    }

    public void setVId(Integer VId) {
        this.VId = VId;
    }

    @Column(name = "v_manufacturer", length = 45)
    public String getVManufacturer() {
        return this.VManufacturer;
    }

    public void setVManufacturer(String VManufacturer) {
        this.VManufacturer = VManufacturer;
    }

    @Column(name = "v_model", length = 45)
    public String getVModel() {
        return this.VModel;
    }

    public void setVModel(String VModel) {
        this.VModel = VModel;
    }

    @Column(name = "v_year")
    public Integer getVYear() {
        return this.VYear;
    }

    public void setVYear(Integer VYear) {
        this.VYear = VYear;
    }

    @Column(name = "v_category", length = 45)
    public String getVCategory() {
        return this.VCategory;
    }

    public void setVCategory(String VCategory) {
        this.VCategory = VCategory;
    }

    @Column(name = "v_transmission", length = 45)
    public String getVTransmission() {
        return this.VTransmission;
    }

    public void setVTransmission(String VTransmission) {
        this.VTransmission = VTransmission;
    }

    @Column(name = "v_milleage")
    public Integer getVMilleage() {
        return this.VMilleage;
    }

    public void setVMilleage(Integer VMilleage) {
        this.VMilleage = VMilleage;
    }

    @Column(name = "v_plate", length = 45)
    public String getVPlate() {
        return this.VPlate;
    }

    public void setVPlate(String VPlate) {
        this.VPlate = VPlate;
    }

    @Column(name = "v_color", length = 45)
    public String getVColor() {
        return this.VColor;
    }

    public void setVColor(String VColor) {
        this.VColor = VColor;
    }

    @Column(name = "v_price", precision = 12, scale = 0)
    public Float getVPrice() {
        return this.VPrice;
    }

    public void setVPrice(Float VPrice) {
        this.VPrice = VPrice;
    }

    @ManyToMany(fetch = FetchType.LAZY)
//  @JsonBackReference
    @JoinTable(name = "order_has_vehicle", catalog = "crud", joinColumns = {
            @JoinColumn(name = "vehicle_v_id", nullable = false, updatable = false) }, inverseJoinColumns = {
                    @JoinColumn(name = "order_o_id", nullable = false, updatable = false),
                    @JoinColumn(name = "order_customer_cust_id", nullable = false, updatable = false),
                    @JoinColumn(name = "order_employee_emp_id", nullable = false, updatable = false) })
    public Set<Order> getOrders() {
        return this.orders;
    }

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }

}

OrderServiceImpl.java

package com.jdm.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jdm.dto.OrderDTO;
import com.jdm.dto.OrderIdDTO;
import com.jdm.dto.VehicleDTO;
import com.jdm.entity.Customer;
import com.jdm.entity.Order;
import com.jdm.entity.OrderId;
import com.jdm.entity.Vehicle;
import com.jdm.repository.CustomerRepository;
import com.jdm.repository.OrderRepository;
import com.jdm.repository.VehicleRepository;
import com.jdm.services.CustomerService;
import com.jdm.services.OrderService;

@Service
public class OrderServiceImpl implements OrderService{

    @Autowired
    private OrderRepository orderRepo;

    @Autowired
    private VehicleRepository vehicleRepo;

    public List<Order> findAllOrder(){  
        return (List<Order>) orderRepo.findAll();
    }

    public Optional<Order> findOrderById(Integer id) {  
        return orderRepo.findById(id);
    }

    public Order saveOrder(OrderDTO orderdto) {

        Order order = new Order();
        OrderId oid = new OrderId();

        oid.setOId(orderdto.getId().getOId());
        oid.setEmployeeEmpId(orderdto.getId().getEmployeeEmpId());
        oid.setCustomerCustId(orderdto.getId().getCustomerCustId());
        order.setId(oid);

        order.setDate(orderdto.getDate());
        order.setTotal(orderdto.getTotal());
//      order.setVehicles(orderdto.getVehicles());

//      Vehicle vehicle = new Vehicle();
//      vehicle.getOrders().add(order);

//      Set<Order> orderlist = new HashSet<Order>();
//      Vehicle v = new Vehicle();
//      orderlist.add(order);
//      v.setOrders(orderlist);


        Set<Vehicle> vehiclelist = new HashSet<Vehicle>();
        vehicleRepo.findAll().forEach(vehiclelist::add);

        for(Vehicle v: vehiclelist) {
            Set<Vehicle> vehicle = new HashSet<Vehicle>();
            Vehicle vdto = new Vehicle();
            vdto.setVId(v.getVId());
            vdto.setVManufacturer(v.getVManufacturer());
            vdto.setVModel(v.getVModel());
            vdto.setVYear(v.getVYear());
            vdto.setVMilleage(v.getVMilleage());
            vdto.setVPlate(v.getVPlate());
            vdto.setVTransmission(v.getVTransmission());
            vdto.setVColor(v.getVColor());
            vdto.setVCategory(v.getVCategory());
            vdto.setVPrice(v.getVPrice());

            order.getVehicles().add(vdto);

//          Set<Order> orderlist = new HashSet<Order>();
//          orderlist.add(order);
//          v.setOrders(orderlist);
        }

        return orderRepo.save(order);
    }

    public void deleteOrder(Integer id) {
        orderRepo.deleteById(id);
    }

    public void updateOrder(Order order) {      
        orderRepo.save(order);
    }
}

ERD图

enter image description here

1 个答案:

答案 0 :(得分:0)

就像@XtremeBaumer一样,您需要删除updatable=false属性以使更新生效。当您要告诉双向关系该关系的拥有方将负责更新时,通常使用该属性。

例如,假设您的Employee或Customer表具有一个Address实体。因此在address实体类中,假设您与Employee或Customer实体具有一对多关系。在这种情况下,您可以提供Address实体中Employee或Customer实体类的updatable=false属性告诉Hibernate,更新Customer或Employee实体不是Address实体类的责任。

此外,您需要在代码中正确定义关系的拥有方。在代码中,您将在两个实体类中提供连接条件。 Read

此外,在您的代码中,实体类直接从端点返回。建议从服务类而不是实体类本身返回DTO对象,以便可以防止无限引用或更好地控制返回的数据。如果您想进一步了解DTO模式,请read