我有两张桌子用户和车辆。
首次添加用户和车辆工作正常。当我尝试将新车辆添加到现有用户获取异常时
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();
}
从两天开始,我正在为此而战。
答案 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
列,这是用户表的外键。