Spring引导,Hibernate,mySql应用程序不支持外键约束

时间:2018-04-24 04:51:20

标签: java mysql hibernate spring-boot

我正在开发Spring启动,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中打开应用程序的数据库并尝试删除记录&#39; city1&#39;来自表&#34; city&#34;通过运行查询:

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=?

并删除&#39; city1&#39;记录表&#34; city&#34;没有任何例外。

我的代码出了什么问题? 为什么应用程序的session.delete(city)不会抛出&#34;外键违规&#34;有点例外吗?

谢谢你,米哈伊尔。

0 个答案:

没有答案