IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

OneToMany ManyToOne - Pere/fils - Suppression du Set


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut OneToMany ManyToOne - Pere/fils - Suppression du Set
    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;
    }
    }
    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;
    }


    }
    Et enfin mon test Junit : bien entendu, je commente tous les tests sauf un avant de le lancer :
    import 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;
    }
    }
    Merci pour votre temps passer à me lire, que vous ayez pu m'aider ou non

  2. #2
    Membre expérimenté Avatar de MaitreKaio
    Profil pro
    Freelance Java / Web / Mobile
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance Java / Web / Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Par défaut
    Bon je me lance, mais j'avoue que j'ai un peu lu en diagonale
    Je me suis arrêté sur ton test, la où tu ajoutes deux fils, et où tu commentes l'ajout du troisième.
    Tu dis que l'ajout du troisième est impossible, à moins de faire un new. C'est tout a fait normal et c'est le comportement de Java, pas spécialement d'Hibernate... Je veux dire que si tu fais un test unitaire en virant tout le code hibernate, tu devrais avoir exactement le même comportement.
    Ton objet parent a une collection de fils. Tant que tu ajoutes des fils en faisant des new, c'est ok. Mais si tu ne fais plus de new, ta variable fils pointe encore sur le dernier élément que tu as ajouté à ta collection, et tu t'en sers à nouveau pour modifier l'instance fils. Tu ne travailles donc pas sur une nouvelle instance (une troisième), mais bien sur la seconde que tu as ajouté précédemment à ta liste.
    J'espère que c'est assez clair

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut Merci
    Effectivement, avec cette explication je me rend compte que cette question était un peu bête . Par contre pour les autres, je n'ai toujours pas réussi à débloquer...
    Merci de ton aide

  4. #4
    Membre expérimenté Avatar de MaitreKaio
    Profil pro
    Freelance Java / Web / Mobile
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance Java / Web / Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Par défaut
    Je te propose de créer non pas un mais plusieurs tests unitaires, mettant en évidence chacun des comportements que tu ne comprends pas, et de revenir vers nous pour nous donner le résultat

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Par défaut
    Hello,

    Alors pour ne pas supprimer le père quand on supprime tous les fils : il suffisait de supprimer le cascade all.

    Ensuite, pour régler les autres problèmes, c'est principalement venu par la gestion des news, notamment de

    parent = parentDAO.get(id);
    if parent==nul {PARENT parent = new parent}

    Enfin, pour comparer la collection, je le fais en amont, et j'effectue un remove des entités qui ne sont plus présentes.

Discussions similaires

  1. Problème suppression @OneToMany< -> @ManyToOne
    Par Invité dans le forum Persistance des données
    Réponses: 0
    Dernier message: 30/06/2010, 23h18
  2. @OneToMany Pere / Fils -> Update
    Par snipes dans le forum JPA
    Réponses: 1
    Dernier message: 27/05/2009, 16h34
  3. synchronisation processus pere fils
    Par Tex-Twil dans le forum POSIX
    Réponses: 6
    Dernier message: 25/10/2006, 11h34
  4. pere/fils
    Par innosang dans le forum C
    Réponses: 10
    Dernier message: 15/03/2006, 20h58
  5. modeliser relation pere fil
    Par flawer dans le forum Débuter
    Réponses: 20
    Dernier message: 12/12/2005, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo