在表"车辆"上插入或更新违反外键约束,车辆与用户表有多对一的关系

时间:2016-12-10 07:53:40

标签: java hibernate

我有两张桌子用户和车辆。

  • 用户与车辆有一对多的关系
  • 车辆与用户有多对一的关系。

首次添加用户和车辆工作正常。当我尝试将新车辆添加到现有用户获取异常时

ERROR: insert or update on table "vehicle" violates foreign key constraint "fk2q70uto2vl2oh4enr071s58yb"
  Detail: Key (vehicleid)=(4) is not present in table "usertraveldo".
UserDO
@Entity
@Table(name="usertraveldo")
public class UserTravelDO implements Serializable {
@GenericGenerator(name = "gen", strategy = "increment")
@GeneratedValue(generator = "gen")
@Id
private int id; 
private String username;
private String password;
private String hint;
private String firstname;
private String middlename;
private String lastname;
private Boolean status;

@JoinColumn(name="addressid")
@OneToOne(cascade = CascadeType.ALL)
private AddressTravelDO address;

@JoinColumn(name="roleid")
@ManyToOne(cascade = CascadeType.ALL)
private RoleMasterDO role;

@Column (name = "vehicleid",updatable=false, insertable=false)
@JsonIgnore
@JoinColumn(name="vehicleid")
@OneToMany(cascade = CascadeType.ALL ,fetch =FetchType.EAGER)
private List<VehicleTravelDO> vehicle = new ArrayList<VehicleTravelDO>();
}

VehicleDO

@Entity
@Table(name="vehicle")
public class VehicleTravelDO implements Serializable {


@GenericGenerator(name = "gen", strategy="increment")
@GeneratedValue(generator = "gen")
@Id
//@Column (name = "vehicleid")
private int vehicleid;
private String vehicletype;
private String vehiclenumber;
private int totalseats;
private int availableseats;
@JsonIgnore
@JoinColumn(name="id")
@ManyToOne(cascade = CascadeType.ALL, fetch =FetchType.EAGER)
private UserTravelDO user;
}

异常

Hibernate: insert into vehicle (availableseats, totalseats, id, vehiclenumber, vehicletype, vehicleid) values (?, ?, ?, ?, ?, ?)
2016-12-09 12:58:59.742  WARN 5872 --- [nio-9001-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 23503
2016-12-09 12:58:59.743 ERROR 5872 --- [nio-9001-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper: ERROR: insert or update on table "vehicle" violates foreign key constraint "fk2q70uto2vl2oh4enr071s58yb"
Detail: Key (vehicleid)=(4) is not present in table "usertraveldo".
2016-12-09 12:58:59.743  INFO 5872 --- [nio-9001-exec-6] o.h.e.j.b.internal.AbstractBatchImpl: HHH000010: On release of batch it still contained JDBC statements
2016-12-09 12:58:59.743 ERROR 5872 --- [nio-9001-exec-6] org.hibernate.internal.SessionImpl: HHH000346: Error during managed flush [could not execute statement]
2016-12-09 12:58:59.751  WARN 5872 --- [nio-9001-exec-6] o.a.cxf.phase.PhaseInterceptorChain: Application {}TravelServiceImpl has thrown exception, unwinding now

服务代码

   public Response addVehicle(VehicleTravelBo vehicle) {
    // TODO Auto-generated method stub
    UserTravelDO userDO = new UserTravelDO();
    Session session =         travelHibernateDao.getSessionFactory().getCurrentSession();
    /*Query query = session.createQuery(HQL_LOAD_ALL_USER_ID);
    query.setParameter("id", vehicle.getUserid());
    userDO = (UserTravelDO) query.uniqueResult();*/

    userDO = session.get(UserTravelDO.class, vehicle.getUserid());
    if(userDO == null)
    {
        System.out.println("notexist");
    }
    else
    {
    System.out.println(userDO.getId());
    VehicleTravelDO vehicleDO = ProfileDtoConverter.convertBOtoDO(vehicle);
    vehicleDO.setUser(userDO);
    session.save(vehicleDO);
    }
    HashMap praf= new HashMap();
    praf.put("message", "user  updated");
    //System.out.println("Leavetable updated successfully");
    return Response.ok(praf).build();

}

从两天开始,我正在为此而战。

1 个答案:

答案 0 :(得分:1)

首先,您应该在交易中工作。

public Response addVehicle(VehicleTravelBo vehicle) {
Session session = travelHibernateDao.getSessionFactory().getCurrentSession();
session.getTransaction().begin();


UserTravelDO userDO = session.get(UserTravelDO.class, vehicle.getUserid());
if(userDO == null)
{
    System.out.println("notexist");
}
else
{
   System.out.println(userDO.getId());
   VehicleTravelDO vehicleDO = ProfileDtoConverter.convertBOtoDO(vehicle);
   userDO.addVehicle(vehicleDO);
}

session.getTransaction().commit();
HashMap praf= new HashMap();
praf.put("message", "user  updated");
//System.out.println("Leavetable updated successfully");
return Response.ok(praf).build();

}

<强>第二即可。您的class UserTravelDO应具有以下方法

public void addVehicle(VehicleTravelDO vehicleTravelDO){
    vehicleTravelDO.setUser(this);
    vehicle.add(vehicleTravelDO);
}

当您在tx内工作时,Hibernate会进行脏检查,因此当您添加新车时,它会检测到它,然后执行相应的调用(可能在tx提交时)。

<强>第三即可。不要在cascade = CascadeType.ALL字段上使用private UserTravelDO user;。让我们考虑你想要拆除单一车辆;然后适当的用户也应该被删除,因为级联。

<强>四即可。您的映射不正确。 在class UserTravelDO使用

@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<VehicleTravelDO> vehicle = new ArrayList<VehicleTravelDO>();

同时更改class VehicleTraverDO。使用以下映射

@JsonIgnore
@ManyToOne
@JoinColumn(name="user_id")
private UserTravelDO user;

请明确您的关联。如果您有oneToMany(与许多VehicleTravelDO关联一个UserTravelDO,那么您应该在user_id表中包含列vehicle,它代表user的外键。

现在,您的车辆表中应该有user_id列,这是用户表的外键。