SpringBoot、hibernate、mysql应用程序不遵守外键约束

8fsztsew  于 2021-06-24  发布在  Mysql
关注(0)|答案(0)|浏览(208)

我正在开发springboot,hibernate,mysql应用程序。我不熟悉spring,hibernate,外键有问题。
以下是我的环境和我在应用程序中使用的代码片段:
环境:

Debian GNU/Linux 9.4 x86_64 (stretch)
  JDK jdk-8u162-linux-x64
  Spring Tool Suite ver: 3.9.4
  Spring boot ver: 2.0.0.RELEASE
  Hibernate and mySql versons are set by Spring boot

代码:

@Entity
@Table(name="city",uniqueConstraints={@UniqueConstraint(columnNames={"name"},name="UK_City_name")})
public class City implements Serializable {
  [...]
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Size(min=NAME_SIZE_MIN,max=NAME_SIZE_MAX)
  @Column(name="name",length=NAME_LENGTH,nullable=false)
  private String name;

  @Column(name="colleges")
  @OneToMany
  @JoinColumn(name="city_id",foreignKey=@ForeignKey(name="FK_college_city_id"))
  private Set<College> colleges = new HashSet<>();
  [...]
}

@Entity
@Table(name="college",uniqueConstraints={@UniqueConstraint(columnNames={"name","city_id"},name="UK_College_name_city_id")})
public class College implements Serializable {
  [...]
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Size(min=NAME_SIZE_MIN,max=NAME_SIZE_MAX)
  @Column(name="name",length=NAME_LENGTH,nullable=false)
  private String name;

  @ManyToOne
  private City city;
  [...]
}

@Controller
@Transactional
public class CityController {
  @Autowired
  CityDao cityDao;
  [...]
  @RequestMapping({"/cityListRemoveItem"})
  public String removeCityHandler(HttpServletRequest request,Model model,@RequestParam(value="id") Long id) {
    City city = null;
    if (id!=null)
      city = cityDao.findCity(id);

    if (city!=null)
      cityDao.remove(city);

    return "redirect:/admin/cityList";
  }
}

@Transactional
@Repository
public class CityDao {
  @Autowired
  private SessionFactory sessionFactory;
  [...]
  public City findCity(Long id) {
    try {
      String qu = "Select c from "+City.class.getName()+" c Where c.id = :id";

      Session session = this.sessionFactory.getCurrentSession();
      Query<City> hibernateQu = session.createQuery(qu,City.class);
      hibernateQu.setParameter("id",id);

      return (City)hibernateQu.getSingleResult();
    }
    catch (NoResultException ex) {
      return null;
    }
  }

  @Transactional(rollbackFor=Exception.class)
  public void remove(City city) {
    Session session = this.sessionFactory.getCurrentSession();

    try {
      session.delete(city);
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  [...]
}

我使用org.hibernate.tool.hbm2ddl.schemaexport创建数据库。exportscript.sql文件的内容是:

create table city (id bigint not null auto_increment,name varchar(15) not null,primary key (id));
create table college (id bigint not null auto_increment,name varchar(91) not null,city_id bigint,primary key (id));
alter table city add constraint UK_City_name unique (name);
alter table college add constraint UK_College_name_city_id unique (name,city_id);
alter table college add constraint FK_college_city_id foreign key (city_id) references city (id);
[...]

为了进行测试,我将以下记录添加到应用程序的数据库中:

Table "City":
Id  name
-----------
 1  'city1'
 2  'city2'

Table "College":
Id  name       city_id
----------------------
 1  'college1'       1
 2  'college2'       2

如果我在squirrelsql中打开应用程序的数据库,并尝试通过运行query从表“city”中删除记录“city1”:

delete from city where id = 1;

我得到一个错误:

Cannot delete or update a parent row: a foreign key constraint fails...

这是很好的,因为它应该是,这是我希望我的申请做。
但事实并非如此。当我尝试从应用程序中删除同一条记录时,hibernate会创建以下查询:

update college set city_id=null where city_id=?
delete from city where id=?

从“city”表中删除“city1”记录,没有任何例外。
我的代码怎么了?为什么应用程序的session.delete(city)不抛出“外键冲突”类异常?
谢谢你,米哈伊尔。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题