有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java hibernate:删除一对多关系中的实体

我有以下错误:

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();
}

我理解问题在于,可能有一个部分在没有场景的情况下是不可能存在的。但现在数据库中的节表是空的,我仍然无法删除该场景。谢谢你的建议


共 (2) 个答案

  1. # 1 楼答案

    通过Query删除实体将绕过通过注释设置的任何级联设置

    我建议先按id查找实体,然后删除实体对象:

    Object scenario = session.load(Scenario.class, id);
    if (scenario != null) {
        session.delete(scenario);
    }
    
  2. # 2 楼答案

    使用cascade=CascadeType.ALLclass Scenario中的所有@ManyToOne关系,因为如果要从数据库中删除任何场景,则不能在数据库中的任何位置引用它

    另一种删除方法是

    Serializable id = new Long(1); //your id
    Object persistentInstance = session.load(Scenario.class, id);
    if (persistentInstance != null) {
        session.delete(persistentInstance);
    }