我正在开发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;有点例外吗?
谢谢你,米哈伊尔。