Bonjour à tous,

J'ai 3 classes : System, RequirementDetails et Compliance. (Un "requirement" référence 0 ou plusieurs "Compliance" et est stocké dans un "System" - comme une arborescence de fichiers).

Dans ma base de données, j'ai 1 table "system", 1 table "requirement", une table "compliance", et une table de jointure "requirement_compliance"

Je veux pouvoir dupliquer tous les systems, requirements et compliances...

Ça duplique tout mes enregistrements (avec des nouveaux ids, les liens mis à jours, etc...).
Sauf que ! Sauf que en plus de me dupliquer mes enregistrement, le lien entre Requirement et Compliance est supprimé de la table de jointure. Et voici ce que je trouve dans les logs :
Hibernate: delete from requirement_compliance where requirement_id=?
Quelqu'un c'est à quoi c'est dû ? J'ai cette erreur depuis que j'ai ajouté la table de jointure. Avant ça le lien entre requirement et compliance été matérialisé par compliance.requirement_id...

Voici comment je procède pour dupliquer mes objets (et les sous objets) : je fais un select puis, pour chaque objet de la liste de résultat, je supprime l'objet du cache hibernate (evict()) et je met l'id à 0. Et ainsi de suite pour chaque sous-objet. Example :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for (RequirementDetails requirement : planSystem.getRequirementsList()) {
	// Clear from cache
	this.getHibernateTemplate().evict(requirement);
 
	// Set the requirement id to 0
	requirement.setId(0);
 
	// Link with the "To" planversion
	requirement.setPlanVersion(planVersionTo);
 
	for (Compliance compliance : requirement.getCompliancesList()) {
		// Clear from cache
		this.getHibernateTemplate().evict(compliance);
 
		// Set the compliance id to 0
		compliance.setId(0);
 
		// Link with the current requirementDetails
		requirement.addCompliance(compliance);
 
	}// End For "compliance"
 
} // End For "requirement"
Cette solution me permet de garder les liens entre les objets dupliqués...

Voici le mapping pour ma classe RequirementDetails :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entity
@Table(name="requirementdetails")
public class RequirementDetails extends AbstractRequirement {
 
	private static final long serialVersionUID = 6902845569210970629L;
 
	//@OneToMany(
		/*mappedBy="requirement",*/
	@ManyToMany(
		fetch=FetchType.EAGER,
		cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
	@JoinTable(
		name="requirement_compliance", 
		joinColumns={@JoinColumn(name="requirement_id")},
		inverseJoinColumns={@JoinColumn(name="compliance_id")}
	)
	@OrderBy("moc")
	private Set<Compliance> compliancesList = new HashSet<Compliance>();
	//...(
et celui de compliance :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@MappedSuperclass
public abstract class AbstractCompliance {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id = 0;
 
	@OneToOne
	@JoinColumn(name="moc_id")
	@OrderBy("name ASC")
	private Moc moc = null;
 
	@OneToOne(
		cascade={
			CascadeType.MERGE, CascadeType.PERSIST, 
			CascadeType.REFRESH
		}
	)
 
	//...