references and microreferences for name relations
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / TaxonNameBase.java
index 3f8417c57a046e2108b3efe6be8e9a2a4c25737f..035707ebb385047d627a779e3e249ee86d02d486 100644 (file)
@@ -11,6 +11,7 @@ package eu.etaxonomy.cdm.model.name;
 
 import java.lang.reflect.Method;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.persistence.Column;
@@ -30,7 +31,6 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlIDREF;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSchemaType;
-import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.log4j.Logger;
@@ -38,7 +38,9 @@ import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
 import org.hibernate.annotations.Index;
 import org.hibernate.annotations.Table;
-import org.hibernate.annotations.Target;
+import org.hibernate.envers.Audited;
+import org.hibernate.search.annotations.Field;
+import org.springframework.util.ReflectionUtils;
 
 import eu.etaxonomy.cdm.model.common.IParsable;
 import eu.etaxonomy.cdm.model.common.IReferencedEntity;
@@ -86,25 +88,21 @@ import eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy;
     "relationsFromThisName",
     "relationsToThisName",
     "status",
-    "descriptions"
-//    "taxonBases"
+    "descriptions",
+    "taxonBases"
 })
 @XmlRootElement(name = "TaxonNameBase")
 @Entity
+@Audited
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 @Table(appliesTo="TaxonNameBase", indexes = { @Index(name = "taxonNameBaseTitleCacheIndex", columnNames = { "titleCache" }) })
-public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INameCacheStrategy> extends IdentifiableEntity<TaxonNameBase> implements IReferencedEntity, IParsable, IRelated {
+public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INameCacheStrategy> extends IdentifiableEntity<S> implements IReferencedEntity, IParsable, IRelated {
 
-       /**
-        * 
-        */
        private static final long serialVersionUID = -4530368639601532116L;
-
        private static final Logger logger = Logger.getLogger(TaxonNameBase.class);
 
-       private static Method methodDescriptionSetTaxonName;
-
        @XmlElement(name = "FullTitleCache")
+       @Column(length=330, name="fullTitleCache")
        private String fullTitleCache;
        
        //if true titleCache will not be automatically generated/updated
@@ -113,12 +111,16 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        
     @XmlElementWrapper(name = "Descriptions")
     @XmlElement(name = "Description")
+    @OneToMany(mappedBy="taxonName", fetch= FetchType.LAZY) 
+       @Cascade({CascadeType.SAVE_UPDATE})
        private Set<TaxonNameDescription> descriptions = new HashSet<TaxonNameDescription>();
        
     @XmlElement(name = "AppendedPhrase")
+    @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
        private String appendedPhrase;
        
     @XmlElement(name = "NomenclaturalMicroReference")
+    @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
        private String nomenclaturalMicroReference;
        
     @XmlAttribute
@@ -134,53 +136,59 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
     @XmlElement(name = "TypeDesignation")
     @XmlIDREF
     @XmlSchemaType(name = "IDREF")
+    @ManyToMany(fetch = FetchType.LAZY)
+       //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
+       @Cascade(CascadeType.SAVE_UPDATE)
        private Set<TypeDesignationBase> typeDesignations = new HashSet<TypeDesignationBase>();
 
     @XmlElement(name = "HomotypicalGroup")
     @XmlIDREF
     @XmlSchemaType(name = "IDREF")
-       private HomotypicalGroup homotypicalGroup = new HomotypicalGroup();
+    @ManyToOne(fetch = FetchType.LAZY)
+       @Cascade({CascadeType.SAVE_UPDATE})
+       private HomotypicalGroup homotypicalGroup;
 
     @XmlElementWrapper(name = "RelationsFromThisName")
     @XmlElement(name = "RelationFromThisName")
-    @XmlIDREF
-    @XmlSchemaType(name = "IDREF")
+    @OneToMany(mappedBy="relatedFrom", fetch= FetchType.LAZY)
+       //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN}) => DELETE_ORPHAN does not work ( org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": eu.etaxonomy.cdm.model.name.TaxonNameBase.relationsFromThisName)
+       @Cascade(CascadeType.SAVE_UPDATE)
        private Set<NameRelationship> relationsFromThisName = new HashSet<NameRelationship>();
 
     @XmlElementWrapper(name = "RelationsToThisName")
     @XmlElement(name = "RelationToThisName")
     @XmlIDREF
     @XmlSchemaType(name = "IDREF")
+    @OneToMany(mappedBy="relatedTo", fetch= FetchType.LAZY)
+       //@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
+       @Cascade(CascadeType.SAVE_UPDATE)
        private Set<NameRelationship> relationsToThisName = new HashSet<NameRelationship>();
 
-    @XmlElementWrapper(name = "NomenclaturalStatus_")
+    @XmlElementWrapper(name = "NomenclaturalStatuses")
     @XmlElement(name = "NomenclaturalStatus")
-    @XmlIDREF
-    @XmlSchemaType(name = "IDREF")
+    @OneToMany(fetch= FetchType.LAZY)
+       @Cascade({CascadeType.SAVE_UPDATE})
        private Set<NomenclaturalStatus> status = new HashSet<NomenclaturalStatus>();
 
-    @XmlTransient
-    //@XmlElementWrapper(name = "TaxonBases")
-    //@XmlElement(name = "TaxonBase")
+    @XmlElementWrapper(name = "TaxonBases")
+    @XmlElement(name = "TaxonBase")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @OneToMany(mappedBy="name", fetch= FetchType.LAZY)
        private Set<TaxonBase> taxonBases = new HashSet<TaxonBase>();
     
-    
-    
-
     @XmlElement(name = "Rank")
        @XmlIDREF
        @XmlSchemaType(name = "IDREF")
+       @ManyToOne(fetch = FetchType.EAGER)
        private Rank rank;
 
-//  FIXME: This must be an IDREF to the corresponding nomenclatural reference.
-//    @XmlTransient
-//    @XmlAnyElement
-       @XmlElement(name = "NomenclaturalReference", type = ReferenceBase.class)
+       @XmlElement(name = "NomenclaturalReference")
     @XmlIDREF
     @XmlSchemaType(name = "IDREF")
-       private INomenclaturalReference nomenclaturalReference;
-
-       static Method methodTaxonBaseSetName;
+    @ManyToOne(fetch = FetchType.LAZY)
+       @Cascade({CascadeType.SAVE_UPDATE})
+       private ReferenceBase nomenclaturalReference;
        
 // ************* CONSTRUCTORS *************/   
        /** 
@@ -191,7 +199,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see #TaxonNameBase(Rank, HomotypicalGroup)
         */
        public TaxonNameBase() {
-               this(null, null);
+               super();
        }
        /** 
         * Class constructor: creates a new taxon name
@@ -242,11 +250,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        }
        
 //********* METHODS **************************************/
-
-       //@Index(name="TaxonNameBaseTitleCacheIndex")
-//     public String getTitleCache(){
-//             return super.getTitleCache();
-//     }
        
        /**
         * Returns the boolean value "false" since the components of <i>this</i> taxon name
@@ -264,7 +267,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        
        public abstract String generateFullTitle();
 
-    @Transient
+       @Transient
        public String getFullTitleCache(){
                if (protectedFullTitleCache){
                        return this.fullTitleCache;                     
@@ -274,6 +277,11 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                }
                return fullTitleCache;
        }
+       
+       @Transient
+       public List<Object> getTaggedName(){
+               return getCacheStrategy().getTaggedName(this);
+       }
 
     public void setFullTitleCache(String fullTitleCache){
                setFullTitleCache(fullTitleCache, PROTECTED);
@@ -289,17 +297,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                this.setProtectedFullTitleCache(protectCache);
        }
        
-       @Column(length=330, name="fullTitleCache")
-       @Deprecated //for hibernate use only
-       protected String getPersistentFullTitleCache(){
-               return getFullTitleCache();
-       }       
-       
-       @Deprecated //for hibernate use only
-       protected void setPersistentFullTitleCache(String fullTitleCache){
-               this.fullTitleCache = fullTitleCache;
-       }
-       
        public boolean isProtectedFullTitleCache() {
                return protectedFullTitleCache;
        }
@@ -320,8 +317,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see    #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
         */
        @Transient
-//     @OneToMany(mappedBy="relatedTo", fetch=FetchType.LAZY)
-//     @Cascade({CascadeType.SAVE_UPDATE})
        public Set<NameRelationship> getNameRelations() {
                Set<NameRelationship> rels = new HashSet<NameRelationship>();
                rels.addAll(getRelationsFromThisName());
@@ -329,10 +324,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                return rels;
        }
        
-//     protected void setNameRelations(Set<NameRelationship> nameRelations) {
-//             this.nameRelations = nameRelations;
-//     }
-       
        /**
         * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from <i>this</i> taxon name to another taxon name
         * and adds it both to the set of {@link #getRelationsFromThisName() relations from <i>this</i> taxon name} and
@@ -349,6 +340,11 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        public void addRelationshipToName(TaxonNameBase toName, NameRelationshipType type, String ruleConsidered){
                NameRelationship rel = new NameRelationship(toName, this, type, ruleConsidered);
        }
+       
+       public void addRelationshipToName(TaxonNameBase toName, NameRelationshipType type, ReferenceBase citation, String microCitation, String ruleConsidered){
+               NameRelationship rel = new NameRelationship(toName, this, type, citation, microCitation, ruleConsidered);
+       }
+       
        /**
         * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from another taxon name to <i>this</i> taxon name
         * and adds it both to the set of {@link #getRelationsToThisName() relations to <i>this</i> taxon name} and
@@ -365,6 +361,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        public void addRelationshipFromName(TaxonNameBase fromName, NameRelationshipType type, String ruleConsidered){
                NameRelationship rel = new NameRelationship(this, fromName, type, ruleConsidered);
        }
+       public void addRelationshipFromName(TaxonNameBase fromName, NameRelationshipType type, ReferenceBase citation, String microCitation, String ruleConsidered){
+               NameRelationship rel = new NameRelationship(this, fromName, type, citation, microCitation, ruleConsidered);
+       }
+
        /**
         * Adds an existing {@link NameRelationship name relationship} either to the set of
         * {@link #getRelationsToThisName() relations to <i>this</i> taxon name} or to the set of
@@ -417,7 +417,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                this.relationsToThisName.remove(nameRelation);
                this.relationsFromThisName.remove(nameRelation);
        }
-
                
        public void removeTaxonName(TaxonNameBase taxonName) {
                Set<NameRelationship> nameRelationships = new HashSet<NameRelationship>();
@@ -481,15 +480,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see    #getRelationsToThisName()
         * @see    #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
         */
-       @OneToMany(mappedBy="relatedFrom", fetch= FetchType.LAZY)
-       @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
        public Set<NameRelationship> getRelationsFromThisName() {
                return relationsFromThisName;
        }
-       private void setRelationsFromThisName(Set<NameRelationship> relationsFromThisName) {
-               this.relationsFromThisName = relationsFromThisName;
-       }
-       
+
        /** 
         * Returns the set of all {@link NameRelationship name relationships}
         * in which <i>this</i> taxon name is involved as a target.
@@ -498,15 +492,9 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see    #getRelationsFromThisName()
         * @see    #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
         */
-       @OneToMany(mappedBy="relatedTo", fetch= FetchType.LAZY)
-       @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
        public Set<NameRelationship> getRelationsToThisName() {
                return relationsToThisName;
        }
-       private void setRelationsToThisName(Set<NameRelationship> relationsToThisName) {
-               this.relationsToThisName = relationsToThisName;
-       }
-
        
        /** 
         * Returns the set of {@link NomenclaturalStatus nomenclatural status} assigned
@@ -517,17 +505,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see     NomenclaturalStatus
         * @see     NomenclaturalStatusType
         */
-       @OneToMany(fetch= FetchType.LAZY)
-       @Cascade({CascadeType.SAVE_UPDATE})
        public Set<NomenclaturalStatus> getStatus() {
                return status;
        }
-       /** 
-        * @see     #getStatus()
-        */
-       protected void setStatus(Set<NomenclaturalStatus> nomStatus) {
-               this.status = nomStatus;
-       }
+
        /** 
         * Adds a new {@link NomenclaturalStatus nomenclatural status}
         * to <i>this</i> taxon name's set of nomenclatural status.
@@ -538,6 +519,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        public void addStatus(NomenclaturalStatus nomStatus) {
                this.status.add(nomStatus);
        }
+       
        /** 
         * Removes one element from the set of nomenclatural status of <i>this</i> taxon name.
         * Type and ruleConsidered attributes of the nomenclatural status object
@@ -598,7 +580,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see                                 #addBasionym(TaxonNameBase, String)
         */
        public void addBasionym(T basionym){
-               addBasionym(basionym, null);
+               addBasionym(basionym, null, null, null);
        }
        /**
         * Assigns a taxon name as {@link NameRelationshipType#BASIONYM() basionym} of <i>this</i> taxon name
@@ -613,9 +595,9 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see                                         #getBasionym()
         * @see                                         #addBasionym(TaxonNameBase)
         */
-       public void addBasionym(T basionym, String ruleConsidered){
+       public void addBasionym(T basionym, ReferenceBase citation, String microcitation, String ruleConsidered){
                if (basionym != null){
-                       basionym.addRelationshipToName(this, NameRelationshipType.BASIONYM(), ruleConsidered);
+                       basionym.addRelationshipToName(this, NameRelationshipType.BASIONYM(), citation, microcitation, ruleConsidered);
                }
        }
        
@@ -632,35 +614,16 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                //TODO implement
                logger.warn("not yet implemented");
        }
-
-
-
-       /**
-        * Returns the {@link eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy cache strategy} used to generate
-        * several strings corresponding to <i>this</i> taxon name
-        * (in particular taxon name caches and author strings).
-        * 
-        * @return  the cache strategy used for <i>this</i> taxon name
-        * @see         eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy
-        * @see     eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy
-        */
-       @Transient
-       public abstract S getCacheStrategy();
-       /** 
-        * @see         #getCacheStrategy()
-        */
-       public abstract void setCacheStrategy(S cacheStrategy);
        
        /** 
         * Returns the taxonomic {@link Rank rank} of <i>this</i> taxon name.
         *
         * @see         Rank
         */
-       @ManyToOne
-       //@Cascade({CascadeType.SAVE_UPDATE})
        public Rank getRank(){
                return this.rank;
        }
+       
        /**
         * @see  #getRank()
         */
@@ -677,10 +640,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see         eu.etaxonomy.cdm.model.reference.INomenclaturalReference
         * @see         eu.etaxonomy.cdm.model.reference.ReferenceBase
         */
-       @ManyToOne
-       @Cascade({CascadeType.SAVE_UPDATE})
-       @Target(ReferenceBase.class)
-       public INomenclaturalReference getNomenclaturalReference(){
+       public ReferenceBase getNomenclaturalReference(){
                return this.nomenclaturalReference;
        }
        /**
@@ -688,10 +648,18 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * The corresponding {@link eu.etaxonomy.cdm.model.reference.ReferenceBase.isNomenclaturallyRelevant nomenclaturally relevant flag} will be set to true
         * as it is obviously used for nomenclatural purposes.
         *
+        * @throws IllegalArgumentException if parameter <code>nomenclaturalReference</code> is not assignable from {@link INomenclaturalReference}
         * @see  #getNomenclaturalReference()
         */
-       public void setNomenclaturalReference(INomenclaturalReference nomenclaturalReference){
-               this.nomenclaturalReference = nomenclaturalReference;
+       public void setNomenclaturalReference(ReferenceBase nomenclaturalReference){
+               if(nomenclaturalReference != null){
+                       if(!INomenclaturalReference.class.isAssignableFrom(nomenclaturalReference.getClass())){
+                               throw new IllegalArgumentException("Parameter nomenclaturalReference is not assignable from INomenclaturalReference");
+                       }
+                       this.nomenclaturalReference = (ReferenceBase)nomenclaturalReference;
+               } else {
+                       this.nomenclaturalReference = null;
+               }
        }
 
        /** 
@@ -702,6 +670,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        public String getAppendedPhrase(){
                return this.appendedPhrase;
        }
+       
        /**
         * @see  #getAppendedPhrase()
         */
@@ -777,34 +746,18 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                this.problemEnds = end;
        }
 
-
-       
-       
 //*********************** TYPE DESIGNATION *********************************************//     
        
-
-       
-
        /** 
         * Returns the set of {@link TypeDesignationBase type designations} assigned
         * to <i>this</i> taxon name.
         * @see     NameTypeDesignation
         * @see     SpecimenTypeDesignation
         */
-       @ManyToMany(fetch = FetchType.LAZY)
-       //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
-       @Cascade(CascadeType.SAVE_UPDATE)
        public Set<TypeDesignationBase> getTypeDesignations() {
                return typeDesignations;
        }
        
-       /** 
-        * @see     #getNameTypeDesignations()
-        */
-       private void setTypeDesignations(Set<TypeDesignationBase> typeDesignations) {
-               this.typeDesignations = typeDesignations;
-       }
-       
        /** 
         * Removes one element from the set of {@link TypeDesignationBase type designations} assigned to
         * <i>this</i> taxon name. The type designation itself will be nullified.
@@ -816,7 +769,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                this.typeDesignations.remove(typeDesignation);
        }
        
-       
        /** 
         * Returns the set of {@link SpecimenTypeDesignation specimen type designations} assigned
         * to <i>this</i> taxon name. The {@link Rank rank} of <i>this</i> taxon name is generally
@@ -885,7 +837,8 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                                boolean isLectoType, 
                                boolean isNotDesignated, 
                                boolean addToAllHomotypicNames) {
-               NameTypeDesignation nameTypeDesignation = new NameTypeDesignation(typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType, isNotDesignated);
+               NameTypeDesignation nameTypeDesignation = new NameTypeDesignation(typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType, isLectoType, isNotDesignated);
+               nameTypeDesignation.setLectoType(isLectoType);
                addTypeDesignation(nameTypeDesignation, addToAllHomotypicNames);
        }
        
@@ -921,12 +874,12 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         *                                                                      added to all taxon names of the homotypical group the typified
         *                                                                      taxon name belongs to
         * @see                                                         #getSpecimenTypeDesignations()
-        * @see                                                         TypeDesignationStatus
+        * @see                                                         SpecimenTypeDesignationStatus
         * @see                                                         SpecimenTypeDesignation
         * @see                                                         TypeDesignationBase#isNotDesignated()
         */
        public void addSpecimenTypeDesignation(Specimen typeSpecimen, 
-                               TypeDesignationStatus status, 
+                               SpecimenTypeDesignationStatus status, 
                                ReferenceBase citation, 
                                String citationMicroReference, 
                                String originalNameString, 
@@ -966,14 +919,16 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         *
         * @see         HomotypicalGroup
         */
-       @ManyToOne
-       @Cascade({CascadeType.SAVE_UPDATE})
+       
        public HomotypicalGroup getHomotypicalGroup() {
                return homotypicalGroup;
        }
-       @Deprecated //only for bidirectional and persistence use
-       protected void setHomotypicalGroup(HomotypicalGroup newHomotypicalGroup) {
-               this.homotypicalGroup = newHomotypicalGroup;            
+       
+       /* 
+        * @see #getHomotypicalGroup()
+        */
+       protected void setHomotypicalGroup(HomotypicalGroup homotypicalGroup) {
+               this.homotypicalGroup = homotypicalGroup;
        }
 
 // *************************************************************************//
@@ -1008,7 +963,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
        /** 
         * Not yet implemented
         */
-       @Transient
        @Deprecated
        public String[] getProblems(){
                logger.warn("getProblems not yet implemented");
@@ -1043,20 +997,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see #getTaxa()
         * @see #getSynonyms()
         */
-       @OneToMany(mappedBy="name", fetch= FetchType.LAZY)
        public Set<TaxonBase> getTaxonBases() {
                return this.taxonBases;
        }
-       /** 
-        * @see     #getTaxonBases()
-        */
-       protected void setTaxonBases(Set<TaxonBase> taxonBases) {
-               if (taxonBases == null){
-                       taxonBases = new HashSet<TaxonBase>();
-               }else{
-                       this.taxonBases = taxonBases;
-               }
-       }
+       
        /** 
         * Adds a new {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon base}
         * to the set of taxon bases using <i>this</i> taxon name.
@@ -1067,9 +1011,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         */
        //TODO protected
        public void addTaxonBase(TaxonBase taxonBase){
+               Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
+               ReflectionUtils.makeAccessible(method);
+               ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {this});
                taxonBases.add(taxonBase);
-               initMethods();
-               invokeSetMethod(methodTaxonBaseSetName, taxonBase);
        }
        /** 
         * Removes one element from the set of {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon bases} that refer to <i>this</i> taxon name.
@@ -1079,33 +1024,11 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see                                 #addTaxonBase(TaxonBase)
         */
        public void removeTaxonBase(TaxonBase taxonBase){
+               Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
+               ReflectionUtils.makeAccessible(method);
+               ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {null});
                taxonBases.remove(taxonBase);
-               initMethods();
-               invokeSetMethodWithNull(methodTaxonBaseSetName, taxonBase);
        }
-
-       private void initMethods(){
-               if (methodTaxonBaseSetName == null){
-                       try {
-                               methodTaxonBaseSetName = TaxonBase.class.getDeclaredMethod("setName", TaxonNameBase.class);
-                               methodTaxonBaseSetName.setAccessible(true);
-                       } catch (Exception e) {
-                               e.printStackTrace();
-                               //TODO handle exception
-                       }
-               }
-               if (methodDescriptionSetTaxonName == null){
-                       try {
-                               methodDescriptionSetTaxonName = TaxonNameDescription.class.getDeclaredMethod("setTaxonName", TaxonNameBase.class);
-                               methodDescriptionSetTaxonName.setAccessible(true);
-                       } catch (Exception e) {
-                               e.printStackTrace();
-                               //TODO handle exception
-                       }
-               }
-       }
-       
-       
        
        /**
         * Returns the set of {@link eu.etaxonomy.cdm.model.taxon.Taxon taxa} ("accepted/correct" names according to any
@@ -1160,17 +1083,10 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see #removeDescription(TaxonNameDescription)
         * @see eu.etaxonomy.cdm.model.description.TaxonNameDescription
         */
-       @OneToMany(mappedBy="taxonName", fetch= FetchType.LAZY) 
-       @Cascade({CascadeType.SAVE_UPDATE})
        public Set<TaxonNameDescription> getDescriptions() {
                return descriptions;
        }
-       /**
-        * @see #getDescriptions()
-        */
-       protected void setDescriptions(Set<TaxonNameDescription> descriptions) {
-               this.descriptions = descriptions;
-       }
+
        /** 
         * Adds a new {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription taxon name description}
         * to the set of taxon name descriptions assigned to <i>this</i> taxon name. The
@@ -1182,8 +1098,9 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see                                 #removeDescription(TaxonNameDescription)
         */
        public void addDescription(TaxonNameDescription description) {
-               initMethods();
-               this.invokeSetMethod(methodDescriptionSetTaxonName, description);
+               java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
+               ReflectionUtils.makeAccessible(field);
+               ReflectionUtils.setField(field, description, this);
                descriptions.add(description);
        }
        /** 
@@ -1197,16 +1114,12 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see                                 eu.etaxonomy.cdm.model.description.TaxonNameDescription#getTaxonName()
         */
        public void removeDescription(TaxonNameDescription description) {
-               initMethods();
-               this.invokeSetMethod(methodDescriptionSetTaxonName, null);
+               java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
+               ReflectionUtils.makeAccessible(field);
+               ReflectionUtils.setField(field, description, null);
                descriptions.remove(description);
        }
        
-       
-       
-       
-       
-       
 // ***********
        /**
         * Returns the boolean value indicating whether a given taxon name belongs
@@ -1218,6 +1131,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @return                         the boolean value of the check
         * @see                            HomotypicalGroup
         */
+       @Transient
        public boolean isHomotypic(TaxonNameBase homoTypicName) {
                if (homoTypicName == null) {
                        return false;
@@ -1232,8 +1146,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
                return false;
        }
        
-       
-       
 //*********  Rank comparison shortcuts   ********************//
        /**
         * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
@@ -1339,7 +1251,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see         #isCodeCompliant()
         * @see         #getHasProblem()
         */
-       @Transient
        abstract public NomenclaturalCode getNomenclaturalCode();
        /* (non-Javadoc)
         * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
@@ -1357,11 +1268,6 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
         * @see         eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
         * @see         eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
         */
-       @Override
-       public String generateTitle() {
-               // TODO Auto-generated method stub
-               logger.warn("not yet implemented");
-               return null;
-       }
-       
+//     @Override
+//     public abstract String generateTitle();
 }