/** * Gets Hibernate session. * * @param tx Cache transaction. * @return Session. */ Session session(@Nullable GridCacheTx tx) { Session ses; if (tx != null) { ses = tx.meta(ATTR_SES); if (ses == null) { ses = sesFactory.openSession(); ses.beginTransaction(); // Store session in transaction metadata, so it can be accessed // for other operations on the same transaction. tx.addMeta(ATTR_SES, ses); if (log.isDebugEnabled()) log.debug("Hibernate session open [ses=" + ses + ", tx=" + tx.xid() + "]"); } } else { ses = sesFactory.openSession(); ses.beginTransaction(); } return ses; }
/** {@inheritDoc} */ @Override public void txEnd(GridCacheTx tx, boolean commit) throws GridException { init(); Session ses = tx.removeMeta(ATTR_SES); if (ses != null) { Transaction hTx = ses.getTransaction(); if (hTx != null) { try { if (commit) { ses.flush(); hTx.commit(); } else hTx.rollback(); if (log.isDebugEnabled()) log.debug("Transaction ended [xid=" + tx.xid() + ", commit=" + commit + ']'); } catch (HibernateException e) { throw new GridException( "Failed to end transaction [xid=" + tx.xid() + ", commit=" + commit + ']', e); } finally { ses.close(); } } } }
/** {@inheritDoc} */ @Override public void put(@Nullable GridCacheTx tx, K key, @Nullable V val) throws GridException { init(); if (log.isDebugEnabled()) log.debug("Store put [key=" + key + ", val=" + val + ", tx=" + tx + ']'); if (val == null) { remove(tx, key); return; } Session ses = session(tx); try { GridCacheHibernateBlobStoreEntry entry = new GridCacheHibernateBlobStoreEntry(toBytes(key), toBytes(val)); ses.saveOrUpdate(entry); } catch (HibernateException e) { rollback(ses, tx); throw new GridException( "Failed to put value to cache store [key=" + key + ", val" + val + "]", e); } finally { end(ses, tx); } }
/** {@inheritDoc} */ @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) @Override public V load(@Nullable GridCacheTx tx, K key) throws GridException { init(); if (log.isDebugEnabled()) log.debug("Store load [key=" + key + ", tx=" + tx + ']'); Session ses = session(tx); try { GridCacheHibernateBlobStoreEntry entry = (GridCacheHibernateBlobStoreEntry) ses.get(GridCacheHibernateBlobStoreEntry.class, toBytes(key)); if (entry == null) return null; return fromBytes(entry.getValue()); } catch (HibernateException e) { rollback(ses, tx); throw new GridException("Failed to load value from cache store with key: " + key, e); } finally { end(ses, tx); } }
/** {@inheritDoc} */ @SuppressWarnings({"JpaQueryApiInspection", "JpaQlInspection"}) @Override public void remove(@Nullable GridCacheTx tx, K key) throws GridException { init(); if (log.isDebugEnabled()) log.debug("Store remove [key=" + key + ", tx=" + tx + ']'); Session ses = session(tx); try { Object obj = ses.get(GridCacheHibernateBlobStoreEntry.class, toBytes(key)); if (obj != null) ses.delete(obj); } catch (HibernateException e) { rollback(ses, tx); throw new GridException("Failed to remove value from cache store with key: " + key, e); } finally { end(ses, tx); } }
/** * Checks availability of a classpath resource. * * @param name Resource name. * @return {@code true} if resource is available and ready for read, {@code false} otherwise. */ private boolean resourceAvailable(String name) { InputStream cfgStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(name); if (cfgStream == null) { log.error("Classpath resource not found: " + name); return false; } try { // Read a single byte to force actual content access by JVM. cfgStream.read(); return true; } catch (IOException e) { log.error("Failed to read classpath resource: " + name, e); return false; } finally { U.close(cfgStream, log); } }
/** * Initializes store. * * @throws GridException If failed to initialize. */ private void init() throws GridException { if (initGuard.compareAndSet(false, true)) { if (log.isDebugEnabled()) log.debug("Initializing cache store."); try { if (sesFactory != null) // Session factory has been provided - nothing to do. return; if (!F.isEmpty(hibernateCfgPath)) { try { URL url = new URL(hibernateCfgPath); sesFactory = new Configuration().configure(url).buildSessionFactory(); if (log.isDebugEnabled()) log.debug("Configured session factory using URL: " + url); // Session factory has been successfully initialized. return; } catch (MalformedURLException e) { if (log.isDebugEnabled()) log.debug("Caught malformed URL exception: " + e.getMessage()); } // Provided path is not a valid URL. File? File cfgFile = new File(hibernateCfgPath); if (cfgFile.exists()) { sesFactory = new Configuration().configure(cfgFile).buildSessionFactory(); if (log.isDebugEnabled()) log.debug("Configured session factory using file: " + hibernateCfgPath); // Session factory has been successfully initialized. return; } // Provided path is not a file. Classpath resource? sesFactory = new Configuration().configure(hibernateCfgPath).buildSessionFactory(); if (log.isDebugEnabled()) log.debug("Configured session factory using classpath resource: " + hibernateCfgPath); } else { if (hibernateProps == null) { U.warn( log, "No Hibernate configuration has been provided for store (will use default)."); hibernateProps = new Properties(); hibernateProps.setProperty("hibernate.connection.url", DFLT_CONN_URL); hibernateProps.setProperty("hibernate.show_sql", DFLT_SHOW_SQL); hibernateProps.setProperty("hibernate.hbm2ddl.auto", DFLT_HBM2DDL_AUTO); } Configuration cfg = new Configuration(); cfg.setProperties(hibernateProps); assert resourceAvailable(MAPPING_RESOURCE); cfg.addResource(MAPPING_RESOURCE); sesFactory = cfg.buildSessionFactory(); if (log.isDebugEnabled()) log.debug("Configured session factory using properties: " + hibernateProps); } } catch (HibernateException e) { throw new GridException("Failed to initialize store.", e); } finally { initLatch.countDown(); } } else if (initLatch.getCount() > 0) U.await(initLatch); if (sesFactory == null) throw new GridException("Cache store was not properly initialized."); }