import java.util.List;
import java.util.Set;
+import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.OrderBy;
import javax.persistence.OrderColumn;
import javax.persistence.Transient;
-import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.log4j.Logger;
+import org.hibernate.LazyInitializationException;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Table;
import org.hibernate.envers.Audited;
import org.hibernate.search.annotations.ContainedIn;
-import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
})
@XmlRootElement(name = "TaxonNode")
@Entity
-@Indexed(index = "eu.etaxonomy.cdm.model.taxon.TaxonNode")
+//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
+//@Indexed(index = "eu.etaxonomy.cdm.model.taxon.TaxonNode")
@Audited
@Table(appliesTo="TaxonNode", indexes = { @Index(name = "taxonNodeTreeIndex", columnNames = { "treeIndex" }) })
@ChildTaxaMustBeLowerRankThanParent(groups = Level3.class)
@XmlElement(name = "treeIndex")
- @Size(max=255)
+ @Column(length=255)
private String treeIndex;
@ManyToOne(fetch = FetchType.LAZY)
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
// TODO @NotNull // avoids creating a UNIQUE key for this field
- @IndexedEmbedded
+ @IndexedEmbedded(includeEmbeddedObjectId=true)
private Classification classification;
@XmlElementWrapper(name = "childNodes")
// ************************* GETTER / SETTER *******************************/
+ @Transient
public Integer getSortIndex() {
+ TaxonNode parent = HibernateProxyHelper.deproxy(this.parent, TaxonNode.class);
+ parent.removeNullValueFromChildren();
+
return sortIndex;
}
/**
@Override
public List<TaxonNode> getChildNodes() {
+
return childNodes;
}
protected void setChildNodes(List<TaxonNode> childNodes) {
@Override
public TaxonNode addChildTaxon(Taxon taxon, int index, Reference citation, String microCitation) {
+ Classification classification = HibernateProxyHelper.deproxy(this.getClassification(), Classification.class);
+ taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
if (this.getClassification().isTaxonInTree(taxon)){
throw new IllegalArgumentException(String.format("Taxon may not be in a classification twice: %s", taxon.getTitleCache()));
}
*/
protected boolean removeChildNode(TaxonNode childNode){
boolean result = true;
-
+ removeNullValueFromChildren();
if(childNode == null){
throw new IllegalArgumentException("TaxonNode may not be null");
}
* @see #deleteChildNode(TaxonNode)
*/
public void removeChild(int index){
+ //TODO: Only as a workaround. We have to find out why merge creates null entries.
TaxonNode child = childNodes.get(index);
child = HibernateProxyHelper.deproxy(child, TaxonNode.class); //strange that this is required, but otherwise child.getParent() returns null for some lazy-loaded items.
Classification classification = parent.getClassification();
//FIXME also set the tree index here for performance reasons
+ classification = HibernateProxyHelper.deproxy(classification, Classification.class);
setClassificationRecursively(classification);
// add this node to the parent's child nodes
+ parent = HibernateProxyHelper.deproxy(parent, TaxonNode.class);
List<TaxonNode> parentChildren = parent.getChildNodes();
+ //TODO: Only as a workaround. We have to find out why merge creates null entries.
+
+ while (parentChildren.contains(null)){
+ parentChildren.remove(null);
+ }
+ parent.updateSortIndex(0);
+ if (index > parent.getChildNodes().size()){
+ index = parent.getChildNodes().size();
+ }
if (parentChildren.contains(this)){
//avoid duplicates
if (parentChildren.indexOf(this) < index){
*/
private void updateSortIndex(int index) {
List<TaxonNode> children = this.getChildNodes();
- for(int i = index; i < children.size(); i++){
+
+
+ for(int i = index; i < children.size(); i++){
TaxonNode child = children.get(i);
if (child != null){
// child = CdmBase.deproxy(child, TaxonNode.class); //deproxy not needed as long as setSortIndex is protected or public #4200
return hasTaxon() ? getTaxon().getNullSafeRank() : null;
}
+ private void removeNullValueFromChildren(){
+ try {
+ if (childNodes.contains(null)){
+ while(childNodes.contains(null)){
+ childNodes.remove(null);
+ }
+ }
+ this.updateSortIndex(0);
+ } catch (LazyInitializationException e) {
+ logger.info("Cannot clean up uninitialized children without a session, skipping.");
+ }
+ }
+
//*********************** CLONE ********************************************************/