diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/.gitignore b/elide-dbmanager/elide-dbmanager-hibernate5/.gitignore
new file mode 100644
index 0000000000..2f7896d1d1
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/pom.xml b/elide-dbmanager/elide-dbmanager-hibernate5/pom.xml
new file mode 100644
index 0000000000..ac5694a826
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/pom.xml
@@ -0,0 +1,103 @@
+
+
+
+ 4.0.0
+ elide-dbmanager-hibernate5
+ jar
+ Elide Hibernate5 Database Manager
+ Elide database manager for Hibernate5 support
+ https://github.com/yahoo/elide
+
+ com.yahoo.elide
+ elide-dbmanager-parent-pom
+ 1.0.0.1-SNAPSHOT
+
+
+
+
+ The Apache Software License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+
+ Yahoo Inc.
+ https://github.com/yahoo
+
+
+
+
+ scm:git:ssh://git@github.com/yahoo/elide.git
+ https://github.com/yahoo/elide.git
+ HEAD
+
+
+
+
+ com.yahoo.elide
+ elide-core
+
+
+ org.hibernate
+ hibernate-core
+ 5.0.2.Final
+
+
+ slf4j-api
+ org.slf4j
+
+
+ xml-apis
+ xml-apis
+
+
+ jasper-runtime
+ tomcat
+
+
+ xerces
+ xerces
+
+
+ jasper-compiler
+ tomcat
+
+
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hibernate5
+ 2.6.3
+
+
+
+ org.testng
+ testng
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+
+
diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManager.java b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManager.java
new file mode 100644
index 0000000000..60e50edda0
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManager.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2015, Yahoo Inc.
+ * Licensed under the Apache License, Version 2.0
+ * See LICENSE file in project root for terms.
+ */
+package com.yahoo.elide.dbmanagers.hibernate5;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterators;
+import com.yahoo.elide.core.DatabaseManager;
+import com.yahoo.elide.core.DatabaseTransaction;
+import com.yahoo.elide.core.EntityDictionary;
+import com.yahoo.elide.core.FilterScope;
+import com.yahoo.elide.core.RequestScope;
+import com.yahoo.elide.core.exceptions.TransactionException;
+import com.yahoo.elide.security.Check;
+import com.yahoo.elide.security.CriteriaCheck;
+import com.yahoo.elide.security.User;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Criterion;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.metadata.ClassMetadata;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import lombok.NonNull;
+import org.hibernate.resource.transaction.spi.TransactionStatus;
+
+/**
+ * Hibernate interface library
+ */
+public class HibernateManager extends DatabaseManager {
+
+ /**
+ * Wraps ScrollableResult as Iterator
+ * @param type of return object
+ */
+ public static class ScrollableIterator implements Iterable, Iterator {
+
+ final private ScrollableResults scroll;
+ private boolean inUse = false;
+ private boolean hasNext;
+
+ public ScrollableIterator(ScrollableResults scroll) {
+ this.scroll = scroll;
+ }
+
+ @Override
+ public Iterator iterator() {
+ if (inUse) {
+ throw new ConcurrentModificationException();
+ }
+
+ if (!scroll.first()) {
+ return Collections.emptyListIterator();
+ }
+
+ inUse = true;
+ hasNext = true;
+ return Iterators.unmodifiableIterator(this);
+ }
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+
+ }
+
+ @Override
+ public @NonNull T next() {
+ @SuppressWarnings("unchecked")
+ @NonNull T row = (T) scroll.get()[0];
+ Preconditions.checkNotNull(row);
+ hasNext = scroll.next();
+ return row;
+ }
+ }
+
+ /**
+ * Hibernate Transaction implementation
+ */
+ public class HibernateTransaction implements DatabaseTransaction {
+
+ private Transaction transaction;
+ private LinkedHashSet deferredTasks = new LinkedHashSet<>();
+
+ /**
+ * Instantiates a new Hibernate transaction.
+ *
+ * @param transaction the transaction
+ */
+ public HibernateTransaction(Transaction transaction) {
+ this.transaction = transaction;
+ }
+
+ @Override
+ public void delete(Object object) {
+ deferredTasks.add(() -> getSession().delete(object));
+ }
+
+ @Override
+ public void save(Object object) {
+ deferredTasks.add(() -> getSession().saveOrUpdate(object));
+ }
+
+ @Override
+ public void flush() {
+ try {
+ for (Runnable task : deferredTasks) {
+ task.run();
+ }
+ deferredTasks.clear();
+ getSession().flush();
+ } catch (HibernateException e) {
+ throw new TransactionException(e);
+ }
+ }
+
+ @Override
+ public void commit() {
+ try {
+ this.flush();
+ this.transaction.commit();
+ } catch (HibernateException e) {
+ throw new TransactionException(e);
+ }
+ }
+
+ @Override
+ public T createObject(Class entityClass) {
+ try {
+ T object = entityClass.newInstance();
+ deferredTasks.add(() -> getSession().persist(object));
+ return object;
+ } catch (InstantiationException | IllegalAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public T loadObject(Class loadClass, String id) {
+ @SuppressWarnings("unchecked")
+ T record = (T) getSession().load(loadClass, Long.valueOf(id));
+ try {
+ Hibernate.initialize(record);
+ } catch (ObjectNotFoundException e) {
+ return null;
+ }
+ return record;
+ }
+
+ @Override
+ public Iterable loadObjects(Class loadClass) {
+ @SuppressWarnings("unchecked")
+ Iterable list = new ScrollableIterator(getSession().createCriteria(loadClass)
+ .scroll(ScrollMode.FORWARD_ONLY));
+ return list;
+ }
+ @Override
+ public Iterable loadObjects(Class loadClass, FilterScope filterScope) {
+ Criterion criterion = buildCriterion(filterScope);
+
+ // if no criterion then return all objects
+ if (criterion == null) {
+ return loadObjects(loadClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable list = new ScrollableIterator(getSession().createCriteria(loadClass)
+ .add(criterion)
+ .scroll(ScrollMode.FORWARD_ONLY));
+ return list;
+ }
+
+ /**
+ * builds criterion if all checks implement CriteriaCheck
+ * @param Filter type
+ * @param filterScope Filter Scope
+ */
+ public Criterion buildCriterion(FilterScope filterScope) {
+ Criterion compositeCriterion = null;
+ List> checks = filterScope.getChecks();
+ RequestScope requestScope = filterScope.getRequestScope();
+ for (Check check : checks) {
+ Criterion criterion;
+ if (check instanceof CriteriaCheck) {
+ criterion = ((CriteriaCheck) check).getCriterion(requestScope);
+ } else {
+ criterion = null;
+ }
+
+ // if no criterion, examine userPermission and ANY state
+ if (criterion == null) {
+ switch (filterScope.getRequestScope().getUser().checkUserPermission(check)) {
+ // ALLOW and ALL try more criteria
+ case ALLOW:
+ if (!filterScope.isAny()) {
+ continue;
+ }
+ break;
+
+ // DENY and ANY check try more criteria
+ case DENY:
+ if (filterScope.isAny()) {
+ continue;
+ }
+ break;
+ }
+
+ // Otherwise no criteria filtering possible
+ return null;
+ } else if (compositeCriterion == null) {
+ compositeCriterion = criterion;
+ } else if (filterScope.isAny()) {
+ compositeCriterion = Restrictions.or(compositeCriterion, criterion);
+ } else {
+ compositeCriterion = Restrictions.and(compositeCriterion, criterion);
+ }
+ }
+ return compositeCriterion;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (this.transaction.getStatus() == TransactionStatus.ACTIVE) {
+ transaction.rollback();
+ throw new IOException("Transaction not closed");
+ }
+ }
+
+ @Override
+ public User accessUser(Object opaqueUser) {
+ return new User(opaqueUser);
+ }
+ }
+
+ private final SessionFactory sessionFactory;
+
+ /**
+ * Initialize HibernateManager and dictionaries
+ *
+ * @param aSessionFactory the a session factory
+ */
+ public HibernateManager(SessionFactory aSessionFactory) {
+ this.sessionFactory = aSessionFactory;
+ }
+
+ @Override
+ public void populateEntityDictionary(EntityDictionary dictionary) {
+ /* bind all entities */
+ for (ClassMetadata meta : sessionFactory.getAllClassMetadata().values()) {
+ dictionary.bindEntity(meta.getMappedClass());
+ }
+ }
+
+ /**
+ * Get current Hibernate session
+ *
+ * @return session
+ */
+ public Session getSession() {
+ Session session = sessionFactory.getCurrentSession();
+ Preconditions.checkNotNull(session);
+ Preconditions.checkArgument(session.isConnected());
+ return session;
+ }
+
+ /**
+ * Start Hibernate transaction
+ *
+ * @return transaction
+ */
+ @Override
+ public DatabaseTransaction beginTransaction() {
+ Session session = sessionFactory.getCurrentSession();
+ Preconditions.checkNotNull(session);
+ return new HibernateTransaction(session.beginTransaction());
+ }
+}
diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/PersistenceManager.java b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/PersistenceManager.java
new file mode 100644
index 0000000000..b3a16f2bdb
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/dbmanagers/hibernate5/PersistenceManager.java
@@ -0,0 +1,104 @@
+package com.yahoo.elide.dbmanagers.hibernate5;
+
+import com.google.common.base.Preconditions;
+import com.yahoo.elide.core.DatabaseManager;
+import com.yahoo.elide.core.DatabaseTransaction;
+import com.yahoo.elide.core.EntityDictionary;
+import com.yahoo.elide.security.User;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.EntityType;
+import java.io.IOException;
+
+/**
+ * Manager for javax.persistence compatible db resource
+ */
+public class PersistenceManager extends DatabaseManager {
+ private final EntityManagerFactory entityManagerFactory;
+
+ public PersistenceManager(EntityManagerFactory entityManagerFactory) {
+ Preconditions.checkNotNull(entityManagerFactory);
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ @Override
+ public void populateEntityDictionary(EntityDictionary dictionary) {
+ for (EntityType entity : entityManagerFactory.getMetamodel().getEntities()) {
+ dictionary.bindEntity(entity.getBindableJavaType());
+ }
+ }
+
+ @Override
+ public DatabaseTransaction beginTransaction() {
+ return new PersistenceTransaction(entityManagerFactory.createEntityManager());
+ }
+
+ public class PersistenceTransaction implements DatabaseTransaction {
+ private final EntityManager entityManager;
+
+ public PersistenceTransaction(EntityManager entityManager) {
+ this.entityManager = entityManager;
+ this.entityManager.getTransaction().begin();
+ }
+
+ @Override
+ public void save(Object entity) {
+ entityManager.persist(entity);
+ }
+
+ @Override
+ public void delete(Object entity) {
+ entityManager.remove(entity);
+ }
+
+ @Override
+ public void flush() {
+ entityManager.flush();
+ }
+
+ @Override
+ public void commit() {
+ flush();
+ entityManager.getTransaction().commit();
+ }
+
+ @Override
+ public T createObject(Class entityClass) {
+ try {
+ T entity = entityClass.newInstance();
+ entityManager.persist(entity);
+ return entity;
+ } catch (InstantiationException | IllegalAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public T loadObject(Class entityClass, String id) {
+ return entityManager.find(entityClass, Long.valueOf(id));
+ }
+
+ @Override
+ public Iterable loadObjects(Class entityClass) {
+ return entityManager.createQuery("from " + entityClass.getName(), entityClass).getResultList();
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ if (entityManager.getTransaction().isActive()) {
+ entityManager.getTransaction().rollback();
+ throw new IOException("Transaction not closed");
+ }
+ } finally {
+ entityManager.close();
+ }
+ }
+
+ @Override
+ public User accessUser(Object opaqueUser) {
+ return new User(opaqueUser);
+ }
+ }
+}
diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/security/CriteriaCheck.java b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/security/CriteriaCheck.java
new file mode 100644
index 0000000000..ad53699bf1
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/src/main/java/com/yahoo/elide/security/CriteriaCheck.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2015, Yahoo Inc.
+ * Licensed under the Apache License, Version 2.0
+ * See LICENSE file in project root for terms.
+ */
+package com.yahoo.elide.security;
+
+import com.yahoo.elide.core.RequestScope;
+
+import org.hibernate.criterion.Criterion;
+
+/**
+ * Extends Check to support Hibernate Criteria to limit SQL query responses.
+ * @param Type of record for Check
+ */
+public interface CriteriaCheck extends Check {
+ /**
+ * @see org.hibernate.criterion.Restrictions
+ */
+ Criterion getCriterion(RequestScope requestScope);
+}
diff --git a/elide-dbmanager/elide-dbmanager-hibernate5/src/test/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManagerTest.java b/elide-dbmanager/elide-dbmanager-hibernate5/src/test/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManagerTest.java
new file mode 100644
index 0000000000..6784bf03e4
--- /dev/null
+++ b/elide-dbmanager/elide-dbmanager-hibernate5/src/test/java/com/yahoo/elide/dbmanagers/hibernate5/HibernateManagerTest.java
@@ -0,0 +1,13 @@
+package com.yahoo.elide.dbmanagers.hibernate5;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class HibernateManagerTest {
+ // TODO: Create tests for our manager
+ @Test
+ public void todo() {
+ System.err.println("Still need to write tests for hibernate3 manager!");
+ }
+}
diff --git a/elide-dbmanager/pom.xml b/elide-dbmanager/pom.xml
index 408464283c..45b8c2f287 100644
--- a/elide-dbmanager/pom.xml
+++ b/elide-dbmanager/pom.xml
@@ -31,6 +31,7 @@
+ elide-dbmanager-hibernate5
elide-dbmanager-hibernate3
elide-dbmanager-inmemorydb