休眠:删除实体在一个一对多的关系
问题描述:
我有一个以下错误:休眠:删除实体在一个一对多的关系
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`spindledb`.`section`, CONSTRAINT `FK_ftoru9cp83n512p9is8x3vo53` FOREIGN KEY (`scenario_id`) REFERENCES `scenario` (`scenario_id`))
这里是我的课:
场景:
@Entity
@Table(name = "scenario")
public class Scenario {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "scenario_id")
private int id;
@Column(name = "title", nullable = false)
private String title;
@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy")
@Column(name = "creation_date", nullable = false)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate creationDate;
@ManyToOne
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "id", nullable = false)
private User user;
@OneToMany(mappedBy = "scenario", orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Plot> plotList = new HashSet<Plot>();
@OneToMany(mappedBy = "scenario", orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Character> characterList = new HashSet<Character>();
@OneToMany(mappedBy = "scenario", cascade=CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@OrderBy("sequence ASC")
private Set<Section> sectionList = new HashSet<Section>();
科:
@Entity
@Table(name = "section")
public class Section {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "section_id")
private int id;
@Size(min = 4, max = 50)
@NotNull
@Column(name = "name")
private String name;
@NotNull
@Column(name = "type")
private String type = SectionType.TEXT.getSectionType();
@Column(name = "visibility")
private boolean visibility;
@NotNull
@Column(name = "sequence")
private int sequence;
@ManyToOne (cascade=CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "scenario_id", nullable = false)
private Scenario scenario;
控制器:
@RequestMapping(value = { "/delete-{id}-scenario" }, method = RequestMethod.GET)
public String deleteScenario(@PathVariable int id) {
scenarioService.deleteScenarioById(id);
return "redirect:/home";
}
方案服务:
@Service("scenarioService")
@Transactional
public class ScenarioServiceImpl implements ScenarioService {
@Autowired
private ScenarioDao dao;
@Override
public Scenario findById(int id) {
return dao.findById(id);
}
@Override
public void saveScenario(Scenario scenario) {
dao.saveScenario(scenario);
}
public void updateScenario(Scenario scenario) {
Scenario entity = dao.findById(scenario.getId());
if(entity!=null){
entity.setTitle(scenario.getTitle());
entity.setCreationDate(scenario.getCreationDate());
}
}
@Override
public void deleteScenarioById(int id) {
dao.deleteScenarioById(id);
}
道
@Repository("scenarioDao")
public class ScenarioDaoImpl extends AbstractDao<Integer, Scenario> implements ScenarioDao {
@Override
public Scenario findById(int id) {
return getByKey(id);
}
@Override
public void saveScenario(Scenario scenario) {
persist(scenario);
}
@Override
public void deleteScenarioById(int id) {
Query query = getSession().createSQLQuery("delete from scenario where id = :id");
query.setString("id", ""+id);
query.executeUpdate();
}
我明白,问题是,有可能是不能没有的情况存在的部分。但是现在数据库中的部分表是空的,我仍然无法删除Scenario。感谢您的建议
答
使用cascade=CascadeType.ALL
与class Scenario
所有@ManyToOne
的关系,因为如果你打算从数据库中删除任何方案它决不能引用数据的基础上任何地方。
另一种方法是删除。
Serializable id = new Long(1); //your id
Object persistentInstance = session.load(Scenario.class, id);
if (persistentInstance != null) {
session.delete(persistentInstance);
}
答
通过Query
删除的实体将绕过您通过注释把任何级联设置。
我建议先找到实体的ID,然后删除实体对象:
Object scenario = session.load(Scenario.class, id);
if (scenario != null) {
session.delete(scenario);
}
遗憾的是没有帮助 – TergOfSky
通过查询删除实体将绕过任何级联设定。所以这真的没有帮助。 – Ish
使用以下技术删除已定义的 http://www.codejava.net/frameworks/hibernate/hibernate-basics-3-ways-to-delete-an-entity-from-the-datastore Serializable id = new Long (1); //你的ID 对象persistentInstance = session.load(Scenario.class,id); (persistentInstance!= null){ session.delete(persistentInstance); } –