Class AnnotationRelation

java.lang.Object
ubic.gemma.model.common.AbstractIdentifiable
ubic.gemma.model.common.description.AnnotationRelation
All Implemented Interfaces:
Identifiable

@Entity public class AnnotationRelation extends AbstractIdentifiable
One term stands in some relation to another term: subject — predicate → object, plus where that came from.

Why this exists. Gemma holds this knowledge in four places and can query it from none of them. A curator writes disease model: left ventricular hypertrophy — induced by — aortic banding and it lands in getPredicate()/getObject(), indexed per-experiment only; ask "which manipulations are asserted to induce left ventricular hypertrophy?" and there is nothing to ask it of. CLO states which disease a cell line derives from and OntologyTerm.getRestrictions() has always been able to read it and is called from nowhere. MGI holds gene-level disease associations we compare against offline and never load. And our own corpus attests pairings by co-occurrence that nobody has written down. This table is one queryable home for all four, with AnnotationRelationBasis recording which.

It is not a disease table. Nothing here names disease, genotype or cell line. Those are particular (subjectCategory, predicate, objectCategory) combinations; cell line → organism part, cell type → organism part, cell line → species and disease → taxon are the same rows with different terms in them. Resist adding a column that only one relation kind would use.

Grain: one row per basis, and for attested bases, per attesting experiment. The same triple legitimately appears several times — once stated by CLO, once harvested from a curator's statement, once per experiment whose annotations co-attest it. Reads aggregate by triple and report the set of bases, because corroboration is decided at read: a relation only AnnotationRelationBasis.CORPUS attests is reported as uncorroborated and ranks below one something else also states.

🛑 Support is counted at read, never stored. This is why getExpressionExperiment() exists instead of a count column. A stored count cannot be ACL-filtered afterwards: the public-only version understates for a curator, and the whole-corpus version leaks the existence of private datasets through the denominator. getAclIsAuthenticatedAnonymouslyMask() is carried for the same reason EXPRESSION_EXPERIMENT2CHARACTERISTIC carries it and is read with the same EE2CAclQueryUtils.formNativeAclRestrictionClause.

Every row is derived, so the table is rebuilt rather than upserted — deleted by basis (or by basis and experiment) and re-inserted. An upsert can only correct rows the new query still produces, which is how EXPRESSION_EXPERIMENT2CHARACTERISTIC ended up with 1,008 rows a full rebuild could not fix. Nothing here is authored, so nothing is lost by dropping it all and recomputing.

See Also:
  • Constructor Details

    • AnnotationRelation

      public AnnotationRelation()
  • Method Details

    • getSubjectValue

      public String getSubjectValue()
    • setSubjectValue

      public void setSubjectValue(String subjectValue)
    • getSubjectValueUri

      @Nullable public String getSubjectValueUri()
    • setSubjectValueUri

      public void setSubjectValueUri(@Nullable String subjectValueUri)
    • getSubjectCategory

      @Nullable public String getSubjectCategory()
    • setSubjectCategory

      public void setSubjectCategory(@Nullable String subjectCategory)
    • getSubjectCategoryUri

      @Nullable public String getSubjectCategoryUri()
    • setSubjectCategoryUri

      public void setSubjectCategoryUri(@Nullable String subjectCategoryUri)
    • getPredicate

      @Nullable public String getPredicate()
    • setPredicate

      public void setPredicate(@Nullable String predicate)
    • getPredicateUri

      @Nullable public String getPredicateUri()
    • setPredicateUri

      public void setPredicateUri(@Nullable String predicateUri)
    • getObjectValue

      public String getObjectValue()
    • setObjectValue

      public void setObjectValue(String objectValue)
    • getObjectValueUri

      @Nullable public String getObjectValueUri()
    • setObjectValueUri

      public void setObjectValueUri(@Nullable String objectValueUri)
    • getObjectCategory

      @Nullable public String getObjectCategory()
    • setObjectCategory

      public void setObjectCategory(@Nullable String objectCategory)
    • getObjectCategoryUri

      @Nullable public String getObjectCategoryUri()
    • setObjectCategoryUri

      public void setObjectCategoryUri(@Nullable String objectCategoryUri)
    • getTaxon

      @Nullable public Taxon getTaxon()
    • setTaxon

      public void setTaxon(@Nullable Taxon taxon)
    • getBasis

      public AnnotationRelationBasis getBasis()
    • getStatus

      public AnnotationRelationStatus getStatus()
    • setStatus

      public void setStatus(AnnotationRelationStatus status)
    • setBasis

      public void setBasis(AnnotationRelationBasis basis)
    • getSource

      @Nullable public String getSource()
    • setSource

      public void setSource(@Nullable String source)
    • getSourceVersion

      @Nullable public String getSourceVersion()
    • setSourceVersion

      public void setSourceVersion(@Nullable String sourceVersion)
    • getEvidenceCode

      @Nullable public GOEvidenceCode getEvidenceCode()
    • setEvidenceCode

      public void setEvidenceCode(@Nullable GOEvidenceCode evidenceCode)
    • getEvidence

      @Nullable public String getEvidence()
    • setEvidence

      public void setEvidence(@Nullable String evidence)
    • getSupportingEvidence

      @Nullable public String getSupportingEvidence()
    • setSupportingEvidence

      public void setSupportingEvidence(@Nullable String supportingEvidence)
    • getExpressionExperiment

      @Nullable public ExpressionExperiment getExpressionExperiment()
    • setExpressionExperiment

      public void setExpressionExperiment(@Nullable ExpressionExperiment expressionExperiment)
    • getLevel

      @Nullable public String getLevel()
    • setLevel

      public void setLevel(@Nullable String level)
    • getAclIsAuthenticatedAnonymouslyMask

      public int getAclIsAuthenticatedAnonymouslyMask()
    • setAclIsAuthenticatedAnonymouslyMask

      public void setAclIsAuthenticatedAnonymouslyMask(int aclIsAuthenticatedAnonymouslyMask)
    • getGeneratedAt

      public Date getGeneratedAt()
    • setGeneratedAt

      public void setGeneratedAt(Date generatedAt)
    • hashCode

      public int hashCode()
      Constant, deliberately.

      The business key here is nine nullable columns wide and is populated through setters, so a key-based hash would be wrong the moment a producer set a field after adding the instance to a set, and an id-based one is wrong by construction (the id appears on persist, moving the object to a different bucket than the one it was filed under). A constant hash degrades a single bucket to a linear scan and is never incorrect. Nothing collects these into large in-memory sets — the reads are native aggregate queries — so the cost is not observable.

      Specified by:
      hashCode in class AbstractIdentifiable
    • equals

      public boolean equals(Object o)
      Description copied from class: AbstractIdentifiable
      Important note: Two objects with the same class and non-null ID must be considered equal. If one or both IDs are nulls, the rest of the state can be used to determine equality.
      Specified by:
      equals in class AbstractIdentifiable
    • toString

      public String toString()
      Overrides:
      toString in class AbstractIdentifiable