Boa noite.
Estou usando o hibernate e estou com um problema de persistencia.
É o seguinte:
Tenho uma tarefa (Task) que tem vários passos(Step).
Task.java
package aron.model;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class Task {
private Integer id;
private String name;
private String description;
private Date date;
private SortedSet<Step> stepList;
public Task() {
this.stepList = new TreeSet<Step>();
}
public Task(Integer id, String name, String description, Date date,
SortedSet<Step> stepList) {
this.id = id;
this.name = name;
this.description = description;
this.date = date;
this.stepList = stepList;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
public SortedSet<Step> getStepList() {
return Collections.unmodifiableSortedSet(this.stepList);
}
public void setStepList(SortedSet<Step> stepList) {
this.stepList = stepList;
}
public void addStep(Step step) {
this.stepList.add(step);
}
public void removeStep(Step step) {
this.stepList.remove(step);
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Step.java
package aron.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
public class Step implements Comparable<Step> {
private Integer id;
private Date date;
private String description;
public Step() {
}
public Step(Integer id, Date date, String description) {
this.id = id;
this.date = date;
this.description = description;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public int compareTo(Step step) {
return this.date.compareTo(step.date);
}
}
Task.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="aron.model.Task" table="task">
<id name="id" type="integer" unsaved-value="50">
<generator class="increment"/>
</id>
<property name="name" type="string" not-null="true" length="50" />
<property name="description" type="string" not-null="true" length="255" />
<property name="date" column="task_date" type="date" not-null="true" length="20" />
<!--set name="stepList" sort="natural">
<key column="task_id" />
<one-to-many class="aron.model.Step" />
</set-->
<set name="stepList" sort="natural" table="task_step">
<key column="task_id" not-null="true" />
<many-to-many unique="true" column="step_id" class="aron.model.Step" />
</set>
</class>
</hibernate-mapping>
e Step.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="aron.model.Step" table="step">
<id name="id" column="id" type="java.lang.Integer">
<generator class="increment"/>
</id>
<property name="description" column="description" type="string" not-null="true" length="255" />
<property name="date" column="step_date" type="date" not-null="true" length="20" />
</class>
</hibernate-mapping>
Meu código para criar e salvar o objeto é:
Step s = new Step (null, new Date(1000), "Desenlvover esse sistema");
SortedSet<Step> set = new TreeSet<Step>();
set.add(s);
Task t= new Task(null, "Projeto de Conclusão", "Projeto de conclusão de curso", new Date(1000), set);
Session session = this.sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(t);
tx.commit();
session.flush();
session.close();
Eu acho que deveria funcionar dessa maneira, mas não dá certo.
Recebo uma exceção:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
...
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`aron/task_step`, CONSTRAINT `FKAC83546EDC164A0` FOREIGN KEY (`step_id`) REFERENCES `step` (`id`))
isso acontece porque o hibernate tenta salvar na tabela historico(task_step) antes de salvar o step.
Hibernate: select max(id) from task
Hibernate: insert into task (name, description, task_date, id) values (?, ?, ?, ?)
Hibernate: insert into task_step (task_id, step_id) values (?, ?)
Alguém já passou por isso? Eu não posso persistir todos os Steps antes de salvar o Task porque em teoria, o hibernate deveria cuidar disto para mim. Por exemplo, se eu apagar um step, adicionar outro e salvar o objeto o hibernate deveria rodar esses comandos para mim certo?
Tentei também fazer uma associação 1-n convencional(comentado no step.hbm.xml), mas o erro é o mesmo, mas ao invés do ultimo comando ser um insert na task_step, é um update alterando o task_id… de novo sem sucesso já que ele não inseriu o Step.
Não, eu não posso utilizar annotations