我正在开发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)不抛出“外键冲突”类异常?
谢谢你,米哈伊尔。
暂无答案!
目前还没有任何答案,快来回答吧!