Bonjour à tous,
Je rencontre un soucis avec un mapping. L'idéal que je souhaiterai atteindre :
Une table père, avec une colonne ID (id du père) et tout un tas de colonnes d'attributs propre aux parents.
Une table fils, avec comme clef unique : id du père + type de fils (gentil, méchant...). Une troisième colonne est présente, avec le nom du fils.
Bien entendu, un père peut avoir plusieurs fils.
mon but :
pouvoir supprimer un père, et que cela supprime ses fils automatiquement. Grace à cascade, cela fonctionne.
pouvoir supprimer un fils ou plusieurs du père : là j'ai quelque soucis, notamment si je supprimer tous les fils, le père est alors supprimé, ce que je ne souhaite pas. Peut être que cela bien du cascade.All , mais je n'ai pas réussi à voir ce qu'il fallait faire.
que si je lui balance un fils avec un id et type déjà présent, il l'update : c'est ok.
pouvoir lui donner directement un groupe d'enfant, qu'il me les rajoute, et qu'il me supprime ceux qui ne sont pas présents (si 'toto' 'gentil' n'est pas dans la liste alros qu'il avait été enregistré la fois précédente, il faut le supprimer) : cela ne fonctionne pas. Je me demande s'il n'y a pas une histoire de Hash à réutiliser.
Merci de m'avoir lu![]()
Ci dessous, mes deux déclarations de tables, ainsi que le test Junit utilisé. Si vous pouvez me dire ce qui, à votre sens, ne semble pas correct, je vous en serais reconnaissant.
package com.model;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import com.StringUtils;
import com.AuditableEntity;
@Entity
@Table(name="TSDS_PARENT")
public class PARENT extends AuditableEntity implements Comparable<PARENT>,Cloneable, Serializable{
private static final long serialVersionUID = 8125255986505476755L;
@SuppressWarnings("serial")
@Embeddable
public static class ID implements Serializable {
@Column(name="TBL_UID_PARENT_ID" ,unique=true, nullable = false, length=6)
private String UID_PARENT_ID ;
public String getUID_PARENT_ID() {
return UID_PARENT_ID;
}
public void setUID_PARENT_ID(String id) {
UID_PARENT_ID = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((UID_PARENT_ID == null) ? 0 : UID_PARENT_ID.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ID other = (ID) obj;
if (UID_PARENT_ID == null) {
if (other.UID_PARENT_ID != null)
return false;
} else if (!UID_PARENT_ID.equals(other.UID_PARENT_ID))
return false;
return true;
}
}
public PARENT() {
super();
}
public PARENT(ID id) {
super();
ID = id;
}
@Id
private ID ID;
public ID getID() {
return ID;
}
public void setID(ID id) {
ID = id;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Column(name="TBL_PARENT_ADRESSE",nullable = false, length=10)
private String PARENT_ADRESSE;
//une dizaine de colonnes
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.ALL})
@JoinColumn(name="TBL_UID_PARENT_ID", updatable=false,insertable=false,referencedColumnName="TBL_UID_PARENT_ID")
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<PARENT_CODE> PARENT_CODEs = new HashSet<PARENT_CODE>();
public Set<PARENT_CODE> getPARENT_CODEs() {
return PARENT_CODEs;
}
public void setPARENT_CODEs(Set<PARENT_CODE> es) {
//PARENT_CODEs = es;
this.PARENT_CODEs = es;
}
//getter & setter of PARENT
public boolean getPARENT_ADRESSE() {
return PARENT_ADRESSE;
}
public void setPARENT_ADRESSE(String adresse) {
PARENT_ADRESSE = adresse;
}
//une dizaine de getter / setter
public int compareTo(PARENT parent) {
int result;
//compare each User columns, return result != 0 if there is a difference
result = ID.getUID_PARENT_ID().compareTo(parent.ID.getUID_PARENT_ID());
if(result != 0){
return result;
}
result = PARENT_ADRESSE.compareTo(parent.getPARENT_ADRESSE());
if(result != 0){
return result;
}
//all column are egals : result = 0
return result;
}
}Et enfin mon test Junit : bien entendu, je commente tous les tests sauf un avant de le lancer :package com.model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import com.pojo.AuditableEntity;
@Entity
@Table(name="TABLE_FILS")
public class PARENTS_FILS extends AuditableEntity implements Comparable<PARENTS_FILS>,Cloneable, Serializable{
private static final long serialVersionUID = 735139132424707929L;
@SuppressWarnings("serial")
@Embeddable
public static class ID implements Serializable {
@Column(name="TBL_UID_PARENT_ID" ,nullable = false, length=6)
private String UID_PARENT_ID ;
@Column(name="UID_PARENT_ID",nullable = false, length=20)
private String CDE_FILS_TYPE;
//getter and setter ID
public String getUID_PARENT_ID() {
return UID_PARENT_ID;
}
public void setUID_PARENT_ID(String UID_FILS_id) {
this.UID_PARENT_ID = UID_FILS_id;
}
public String getCDE_FILS_TYPE() {
return CDE_FILS_TYPE;
}
public void setCDE_FILS_TYPE(String CDE_FILS_type) {
this.CDE_FILS_TYPE = CDE_FILS_type;
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(this.getUID_PARENT_ID())
.append(this.getCDE_FILS_TYPE())
.toHashCode();
}
public boolean equals(Object other) {
if ( (this == other ) ) return true;
if ( !(other instanceof PARENTS_FILS.ID) ) return false;
PARENTS_FILS.ID castOther = (PARENTS_FILS.ID) other;
return new EqualsBuilder()
.append(this.getUID_PARENT_ID(), castOther.getUID_PARENT_ID())
.append(this.getCDE_FILS_TYPE(), castOther.getCDE_FILS_TYPE())
.isEquals();
}
@Override
public String toString() {
return getUID_PARENT_ID() + " - " + getCDE_FILS_TYPE();
}
}
public PARENTS_FILS() {
super();
}
public PARENTS_FILS(ID id) {
super();
ID = id;
}
@Id
private ID ID;
public ID getID() {
return ID;
}
public void setID(ID id) {
ID = id;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Column(name="TBL_TXT_NOM_FILS",length=100)
private String TXT_NOM_FILS;
public String getTXT_NOM_FILS() {
return TXT_NOM_FILS;
}
public void setTXT_NOM_FILS(String CDE_FILS_value) {
TXT_NOM_FILS = CDE_FILS_value;
}
@ManyToOne(fetch=FetchType.LAZY,cascade =CascadeType.ALL/*, targetEntity=PARENT.class*/ )
@JoinColumn(name ="TBL_UID_PARENT_ID" ,updatable=false,insertable=false )
//@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private PARENT parent;
public PARENT getUser() {
return parent;
}
public void setUser(PARENT parent) {
this.parent = parent;
}
/*@ManyToOne
@JoinColumn(name="TBL_TXT_TEST")
public PARENT getPARENT() {
return PARENT;
}
public void setPARENT(PARENT parent) {
PARENT = parent;
}*/
public int compareTo(PARENTS_FILS parent) {
int result;
//compare each User columns, return result != 0 if there is a difference
result = ID.getUID_PARENT_ID().compareTo(parent.ID.getUID_PARENT_ID());
if(result != 0){
return result;
}
result = TXT_NOM_FILS.compareTo(parent.getTXT_NOM_FILS());
if(result != 0){
return result;
}
//all column are egals : result = 0
return result;
}
}
Merci pour votre temps passer à me lire, que vous ayez pu m'aider ou nonimport org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests;
import org.springframework.test.annotation.Rollback;
import com....impl.ParentDAOImpl;
import com.model.PARENT;
import com.model.PARENTS_FILS;
public class ParentsFilsTest extends AbstractAnnotationAwareTransactionalTests {
protected ParentDAOImpl parentDAO;
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:Synchronizer-service.xml"};
}
@Rollback(false)
public void test(){
PARENT parent = new PARENT();
PARENT.ID id = new PARENT.ID();
id.setUID_PARENT_ID("toto8");
//test delete fils
//PROBLEME : supprime bien les fils, mais également le père
parent = parentDAO.get(id);
//for(PARENT_FILS fils : parent.getPARENT_FILSs()){
// fils.setUser(null);
//}
parent.getPARENT_FILSs().clear();
parentDAO.saveOrUpdate(parent);
//*/
//to test remove
//*
parent = parentDAO.get(id);
parentDAO.delete(parent);
///*
// to test create & update
//*
parent.setID(id);
parent.setADRESSE("forum Hibernate");
PARENT_FILS fils = new PARENT_FILS();
PARENT_FILS.ID filsId = new PARENT_FILS.ID();
//first fils
//*
filsId.setUID_USER_ID("toto8");
filsId.setCDE_FILS_TYPE("gentil");
fils.setID(filsId);
fils.setTXT_NOM_FILS("toto8filsgentil");
fils.setUser(parent);
parent.getPARENT_FILSs().add(fils);
parentDAO.saveOrUpdate(parent);//*/
//second fils
fils = new PARENT_FILS();
filsId = new PARENT_FILS.ID();
filsId.setUID_USER_ID("toto8");
filsId.setCDE_FILS_TYPE("mechant");
fils.setID(filsId);
fils.setTXT_NOM_FILS("toto8filsmechant");
fils.setUser(parent);
parent.getPARENT_FILSs().add(fils);
//IMPOSSIBLE de faire un deuxième add sans new, il n'enregistrera alors que le dernier (en fait il fera un insert puis des update), même si l'id+ type est différent
/*filsId.setUID_USER_ID("toto8");
filsId.setCDE_FILS_TYPE("pass3");
fils.setID(filsId);
fils.setTXT_NOM_FILS("toto8pass3");
fils.setUser(parent);
parent.getPARENT_FILSs().add(fils);*/
parentDAO.saveOrUpdate(parent);
//*/
}
public void setParentDAO(ParentDAOImpl parentDAO) {
this.parentDAO = parentDAO;
}
}![]()
Partager