Java 在表中插入或更新;车辆“;违反外键约束,车辆与用户表存在多对一关系

Java 在表中插入或更新;车辆“;违反外键约束,车辆与用户表存在多对一关系,java,hibernate,Java,Hibernate,我有两张表,用户和车辆 用户与车辆和车辆之间存在一对多关系 车辆与用户之间存在多对一关系 第一次添加用户和车辆运行良好。当我尝试向现有用户添加新车辆时,出现异常 例外情况 Hibernate: insert into vehicle (availableseats, totalseats, id, vehiclenumber, vehicletype, vehicleid) values (?, ?, ?, ?, ?, ?) 2016-12-09 12:58:59.742 WARN 587

我有两张表,用户和车辆

  • 用户与车辆和车辆之间存在一对多关系
  • 车辆与用户之间存在多对一关系
第一次添加用户和车辆运行良好。当我尝试向现有用户添加新车辆时,出现异常

例外情况

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();

}

从两天开始,我一直在和这个战斗

首先,您应该在事务中工作

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();
}

。您的
类UserTravelDO
应具有以下方法

public void addVehicle(VehicleTravelDO vehicleTravelDO){
    vehicleTravelDO.setUser(this);
    vehicle.add(vehicleTravelDO);
}
当您在tx内工作时,Hibernate执行脏检查,因此当您添加新车辆时,它将检测到它,然后执行相应的调用(可能是在tx提交时)

第三。不要使用
cascade=CascadeType.ALL
对您的
私人用户Traveldo用户字段。让我们考虑一下要删除单个车辆;然后适当的用户也应该被删除,因为级联

第四。您的映射不正确。 在您的
类UserTravelDO
中使用

@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<VehicleTravelDO> vehicle = new ArrayList<VehicleTravelDO>();
请明确您的关联。如果您有一个omany(像许多
VehicleTravelDO
与一个
UserTravelDO
关联),那么您应该在
vehicle
表中有一列
user\u id
,该列表示
user
的外键


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

首先,您应该在事务中工作

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();
}

Second。您的
类用户Traveldo
应具有以下方法

public void addVehicle(VehicleTravelDO vehicleTravelDO){
    vehicleTravelDO.setUser(this);
    vehicle.add(vehicleTravelDO);
}
当您在tx内工作时,Hibernate执行脏检查,因此当您添加新车辆时,它将检测到它,然后执行相应的调用(可能是在tx提交时)

< > >强>第三< /强>不要使用<代码>级联=CasCADEType。所有< /代码>在您的代码>私人用户旅行用户;字段。让我们考虑您要删除单个车辆;然后适当的用户也应该被删除,因为级联。 第四个。您的映射不正确。 在您的
类UserTravelDO
中使用

@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<VehicleTravelDO> vehicle = new ArrayList<VehicleTravelDO>();
请明确您的关联。如果您有一个omany(像许多
车辆旅行社一样
与一个
用户旅行社
关联,那么您应该在
车辆
表中有一列
用户id
,它代表
用户
的外键


因此,现在,您的车辆表中应该有
user\u id
列,这是用户表的外键。

感谢您的回复。即使在更改代码后,也会出现相同的错误@tara在我的项目中,双向映射意味着用户与车辆有一对一的关系,车辆与车辆有多对一的关系第个用户,当我尝试向现有用户添加多个车辆时,我得到“错误:在表“vehicle”上插入或更新违反外键约束“fk2q70uto2vl2oh4enr071s58yb”详细信息:键(vehicleid)=(4)不在表“usertraveldo”中。vehicleid)=(4)不在表usertraveldo中”,其中id为4的车辆是要添加的新车辆,为什么它要求我将其显示在用户表侧。您的双向关联是一对多和多对一。您说“用户与车辆有一对一关系,车辆与用户有多对一关系”是非常错误的“为什么它要我把它放在用户桌边?"因为您的映射是错误的。您的表vehicle应该包含用户表的外键。表示外键的列的名称是什么?Ya vehicle表包含userid作为外键。感谢您的响应。即使更改了您建议的代码@TarasIn my project存在双向映射我,也会出现相同的错误ans用户与车辆有一对一关系,车辆与用户有多对一关系,当我尝试向现有用户添加多个车辆时,我得到“错误:在表中插入或更新“车辆”违反外键约束“fk2q70uto2vl2oh4enr071s58yb”详细信息:键(vehicleid)=(4)不存在于表“usertraveldo”。vehicleid)=(4) 在表usertraveldo中不存在,其中id为4的车辆是要添加的新车辆,为什么它要求我将其显示在用户表侧。您的双向关联是一对一和多对一。您说“用户与车辆有一对一关系,车辆与用户有多对一关系”是非常错误的“为什么它要求我将其显示在用户表侧?”因为您的映射错误。您的表车辆应该包含用户表的外键。表示外键的列的名称是什么?车辆表包含userid作为外键。
@JsonIgnore
@ManyToOne
@JoinColumn(name="user_id")
private UserTravelDO user;