List of usage examples for org.hibernate Session setCacheMode
void setCacheMode(CacheMode cacheMode);
From source file:org.unitime.timetable.solver.instructor.InstructorSchedulingDatabaseLoader.java
License:Apache License
public void load() throws Exception { ApplicationProperties.setSessionId(iSessionId); org.hibernate.Session hibSession = null; Transaction tx = null;//from w ww. j a va2 s .c o m try { hibSession = TimetableManagerDAO.getInstance().createNewSession(); hibSession.setCacheMode(CacheMode.IGNORE); hibSession.setFlushMode(FlushMode.COMMIT); tx = hibSession.beginTransaction(); load(hibSession); tx.commit(); } catch (Exception e) { iProgress.fatal("Unable to load input data, reason: " + e.getMessage(), e); tx.rollback(); } finally { // here we need to close the session since this code may run in a separate thread if (hibSession != null && hibSession.isOpen()) hibSession.close(); } }
From source file:ubic.gemma.persistence.service.association.coexpression.CoexpressionDaoImpl.java
License:Apache License
@Override public void createOrUpdate(BioAssaySet bioAssaySet, List<NonPersistentNonOrderedCoexpLink> links, LinkCreator c, Set<Gene> genesTested) { // assumption is that these are _all_ the links for this experiment assert !links.isEmpty(); assert bioAssaySet != null; assert c != null; Collections.sort(links);/*from w w w. j ava2 s . co m*/ Session sess = this.getSessionFactory().getCurrentSession(); sess.setCacheMode(CacheMode.IGNORE); // to determine the species Gene gene = (Gene) sess.get(Gene.class, links.iterator().next().getFirstGene()); String geneLinkClassName = CoexpressionQueryUtils.getGeneLinkClassName(gene); /* * Check that there are no links for this experiment. */ if (this.countLinks(gene.getTaxon(), bioAssaySet) > 0) { throw new IllegalStateException( "There are already links for given bioAssaySet; they must be deleted before proceeding"); } /* * Attempt to save database trips */ Map<NonPersistentNonOrderedCoexpLink, Boolean> existingResults = this.preFetch(links); String s = "from " + geneLinkClassName + " where firstGene =:f and secondGene=:s and positiveCorrelation=:pc"; Query q = sess.createQuery(s); SQLQuery updateFlippedLinkQuery = sess .createSQLQuery("UPDATE " + CoexpressionQueryUtils.getGeneLinkTableName(gene.getTaxon()) + " SET SUPPORT=:s WHERE FIRST_GENE_FK=:g2 AND SECOND_GENE_FK=:g1 AND POSITIVE=:po"); // map of linkid to links, for establishing the EE-level links. TreeMap<Long, NonPersistentNonOrderedCoexpLink> linkIds = new TreeMap<>(); // keep order so for this experiment // they are in order. Set<Long> seenExistingLinks = new HashSet<>(); // for sanity checks. Set<NonPersistentNonOrderedCoexpLink> seenNewLinks = new HashSet<>(); // for sanity checks. Set<SupportDetails> seenNewSupportDetails = new HashSet<>(); // for sanity checks. int numNew = 0; int numUpdated = 0; int progress = 0; int BATCH_SIZE = 1024; // make a multiple of jdbc batch size... Map<SupportDetails, Gene2GeneCoexpression> batchToCreate = new LinkedHashMap<>(); List<Gene2GeneCoexpression> newFlippedLinks = new ArrayList<>(); Set<Long> genesWithUpdatedData = new HashSet<>(); sess.flush(); sess.clear(); // for each link see if there is already an entry; make a new one if necessary or update the old one. CoexpressionDaoImpl.log.info("Starting link processing"); for (NonPersistentNonOrderedCoexpLink proposedG2G : links) { Long firstGene = proposedG2G.getFirstGene(); Long secondGene = proposedG2G.getSecondGene(); // There is an index for f+s, but querying one-at-a-time is going to be slow. I attempted to speed it up by // fetching all links for a gene when we see it, but this causes problems with data being stale. Prefetching // with just the ability to tell if a link is new or not takes a lot of memory and doesn't speed things up // much. Trying keeping an index of which links a gene has, so we know whether we need to check the database // or not. // // Currently it takes about 1 minute to process 10k links on a relatively small database, much of this is // the findLink call. Gene2GeneCoexpression existingLink = this.findLink(q, proposedG2G, existingResults); /* * To speed this up? * * - Fetch all links for a gene in one batch, instead of looping over them one at a time. The problem is the * flipped links involve other genes that we fetch later in the same transaction, and this all has to be * done in one transaction. I experimented with this already */ if (existingLink == null) { // initialize the supportdetails SupportDetails sd = c.createSupportDetails(firstGene, secondGene, proposedG2G.isPositiveCorrelation()); sd.addEntity(bioAssaySet.getId()); assert sd.getNumIds() > 0; assert sd.isIncluded(bioAssaySet.getId()); // Must be unique assert !seenNewSupportDetails.contains(sd) : "Already saw " + sd + " while processing " + proposedG2G; assert proposedG2G.getLink() != null; batchToCreate.put(sd, proposedG2G.getLink()); if (seenNewLinks.contains(proposedG2G)) { CoexpressionDaoImpl.log.warn( "The data passed had the same new link represented more than once: " + proposedG2G); continue; } seenNewSupportDetails.add(sd); seenNewLinks.add(proposedG2G); if (CoexpressionDaoImpl.log.isDebugEnabled()) CoexpressionDaoImpl.log.debug("New: " + proposedG2G); numNew++; } else { // This code assumes that the flipped version is in the database, but we don't retrieve it // yet. also note that the support of the existing link could be zero, if DELETE_ORPHAN_LINKS = false // (or if initializeLinksFromExistingData was used) // Sanity check. If this happens, there must be two versions of the same link already in the input. if (seenExistingLinks.contains(existingLink.getId())) { throw new IllegalStateException( "The data passed had the same existing link represented more than once: " + existingLink); } /* sanity check that we aren't adding dataset twice; we might be able make this an assertion instead. */ if (existingLink.isSupportedBy(bioAssaySet)) { throw new IllegalStateException("Support for this experiment already exists for " + existingLink + ", must be deleted first"); } // cache old support for sanity check int oldSupport = existingLink.getSupportDetails().getNumIds(); // update the support existingLink.getSupportDetails().addEntity(bioAssaySet.getId()); existingLink.updateNumDatasetsSupporting(); // there is no cascade... on purpose. sess.update(existingLink.getSupportDetails()); assert oldSupport + 1 == existingLink.getNumDatasetsSupporting(); assert existingLink.getSupportDetails().getNumIds() == oldSupport + 1; // track so we add corresponding Experiment-level links later. linkIds.put(existingLink.getId(), new NonPersistentNonOrderedCoexpLink(existingLink)); seenExistingLinks.add(existingLink.getId()); /* * The flipped link is asserted to be in the database. The support details is already dealt with; we * just have to update the support value. */ int numFlippedUpdated = updateFlippedLinkQuery .setParameter("s", existingLink.getNumDatasetsSupporting()) .setParameter("g2", proposedG2G.getSecondGene()) .setParameter("g1", proposedG2G.getFirstGene()) .setParameter("po", proposedG2G.isPositiveCorrelation() ? 1 : 0).executeUpdate(); assert numFlippedUpdated == 1 : "Flipped link missing for " + proposedG2G + " [" + numFlippedUpdated + "]"; numUpdated++; if (CoexpressionDaoImpl.log.isDebugEnabled()) CoexpressionDaoImpl.log.debug("Updated: " + proposedG2G); } genesWithUpdatedData.add(firstGene); genesWithUpdatedData.add(secondGene); if (++progress % 5000 == 0) { CoexpressionDaoImpl.log.info("Processed " + progress + "/" + links.size() + " gene-level links..." + numUpdated + " updated, " + numNew + " new"); } if (batchToCreate.size() >= BATCH_SIZE) { newFlippedLinks.addAll(this.saveBatchAndMakeFlipped(sess, linkIds, batchToCreate, c)); } else if (numUpdated > 0 && numUpdated % BATCH_SIZE == 0) { sess.flush(); sess.clear(); } } // loop over links // tail end batch if (!batchToCreate.isEmpty()) { // we make the flipped links later to optimize their ordering. newFlippedLinks.addAll(this.saveBatchAndMakeFlipped(sess, linkIds, batchToCreate, c)); } // flush the updated ones one last time... if (numUpdated > 0) { sess.flush(); sess.clear(); } assert links.size() == linkIds.size(); CoexpressionDaoImpl.log.info(numUpdated + " updated, " + numNew + " new links"); /* * sort and save the accumulated new flipped versions of the new links, which reuse the supportDetails. In the * flipped links, the first gene is the second gene and vice versa. Continue to accumulate the flipped links. */ CoexpressionDaoImpl.log.info("Saving " + newFlippedLinks.size() + " flipped versions of new links ..."); Collections.sort(newFlippedLinks, new Comparator<Gene2GeneCoexpression>() { @Override public int compare(Gene2GeneCoexpression o1, Gene2GeneCoexpression o2) { return o1.getFirstGene().compareTo(o2.getFirstGene()); } }); progress = 0; for (Gene2GeneCoexpression gl : newFlippedLinks) { sess.save(gl); if (++progress % 5000 == 0) { CoexpressionDaoImpl.log.info("Processed " + progress + "/" + newFlippedLinks.size() + " new flipped gene-level links..."); } if (progress % BATCH_SIZE == 0) { sess.flush(); sess.clear(); } } /* * Save experiment-level links */ CoexpressionDaoImpl.log .info("Saving " + linkIds.size() + " experiment-level links (plus flipped versions) ..."); this.saveExperimentLevelLinks(sess, c, linkIds, bioAssaySet); if (genesTested != null) this.updatedTestedIn(bioAssaySet, genesTested); this.updateGeneCoexpressedWith(links); // kick anything we updated out of the cache. int numRemovedFromCache = this.gene2GeneCoexpressionCache.remove(genesWithUpdatedData); if (numRemovedFromCache > 0) CoexpressionDaoImpl.log.info(numRemovedFromCache + " results evicted from cache"); // flush happens on commit... CoexpressionDaoImpl.log.info("Done, flushing changes ..."); }
From source file:ubic.gemma.persistence.service.association.coexpression.CoexpressionDaoImpl.java
License:Apache License
@Override @Transactional/* w ww . j av a2 s .c om*/ public void deleteLinks(Taxon t, BioAssaySet experiment) { Session sess = this.getSessionFactory().getCurrentSession(); sess.setCacheMode(CacheMode.IGNORE); CoexpressionDaoImpl.log.info("Fetching any old coexpression ..."); Collection<Gene2GeneCoexpression> links = this.getCoexpression(t, experiment); Set<NonPersistentNonOrderedCoexpLink> toRemove = new HashSet<>(); // even if there are no links, we shouldn't assume we can bail; the 'tested-in' information might be there. if (!links.isEmpty()) { CoexpressionDaoImpl.log.info("Removing coexpression information for " + experiment + "; updating " + links.size() + " links (count includes flipped versions)."); // adjust gene-level links int count = 0; int numWithZeroSupportLeft = 0; int BATCH_SIZE = 1024; Collection<SupportDetails> supportDetailsToDelete = new HashSet<>(); Collection<SupportDetails> supportDetailsToUpdate = new HashSet<>(); Collection<Long> genesAffected = new HashSet<>(); for (Gene2GeneCoexpression g2g : links) { genesAffected.add(g2g.getFirstGene()); genesAffected.add(g2g.getSecondGene()); // decrement support; details are shared by both links, just update it once! SupportDetails sd = g2g.getSupportDetails(); if (!supportDetailsToUpdate.contains(sd) && !supportDetailsToDelete.contains(sd)) { /* * If we already saw the supportDetails it might already be zero. But if we didn't, it can't. */ assert g2g.getNumDatasetsSupporting() > 0 : "Support was " + g2g.getNumDatasetsSupporting() + " for " + g2g; sd.removeEntity(experiment.getId()); assert !sd.getIds().contains(experiment.getId()); supportDetailsToUpdate.add(sd); } g2g.updateNumDatasetsSupporting(); assert g2g.getNumDatasetsSupporting() >= 0; if (g2g.getNumDatasetsSupporting() == 0) { /* * we might still want to keep it, on the presumption that it will get filled back in. */ if (CoexpressionDaoImpl.DELETE_ORPHAN_LINKS) { sess.delete(g2g); // it might be in here already (flipped), but that's okay. supportDetailsToDelete.add(sd); // from the quickindex. But leave it there otherwise. toRemove.add(new NonPersistentNonOrderedCoexpLink(g2g)); } else { sess.update(g2g); } numWithZeroSupportLeft++; } else { sess.update(g2g); } if (++count % 10000 == 0) { CoexpressionDaoImpl.log .info("Removed support for " + count + " links for " + experiment + "..."); } if (count % BATCH_SIZE == 0) { sess.flush(); sess.clear(); } } sess.flush(); sess.clear(); this.updateModifiedSupportDetails(experiment, supportDetailsToDelete, supportDetailsToUpdate); if (CoexpressionDaoImpl.DELETE_ORPHAN_LINKS) { CoexpressionDaoImpl.log.info("Adjusted " + links.size() + " gene-level links supported by the experiment; " + numWithZeroSupportLeft + " links removed from the system as support dropped to zero."); } else { CoexpressionDaoImpl.log.info("Adjusted " + links.size() + " gene-level links supported by the experiment; " + numWithZeroSupportLeft + " gene-level links now have support dropped to zero but they were left in place"); } // remove the ExperimentCoexpressionLinks int numDeleted = sess.createQuery( "delete from " + CoexpressionQueryUtils.getExperimentLinkClassName(t) + " where experiment=:ee") .setParameter("ee", experiment).executeUpdate(); CoexpressionDaoImpl.log.info("Deleted " + numDeleted + " experiment-level links"); // invalidate the cache. int numRemovedFromCache = gene2GeneCoexpressionCache.remove(genesAffected); if (numRemovedFromCache > 0) CoexpressionDaoImpl.log.info(numRemovedFromCache + " results evicted from cache"); } // we do NOT redo the node degree information, which will be refreshed "periodically" // we always have to do this, even if there are no links. this.removeTestedIn(t, experiment); // update our quick index if (!toRemove.isEmpty()) this.removeCoexpressedWith(toRemove); }