// Path: src/main/java/com/eclecticlogic/pedal/provider/Consumer.java
// public interface Consumer<T> {
//     
//     
//     void accept(T value);
// 
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/provider/Function.java
// public interface Function<T, R> {
// 
//     R apply(T value);
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/provider/ProviderAccessSpi.java
// public interface ProviderAccessSpi extends ProviderAccess {
// 
//     /**
//      * @param entityMangager JPA entity manager reference.
//      * @param work Execute the work passing in the underlying JDBC connection object.
//      */
//     public void run(EntityManager entityManager, Consumer<Connection> work);
// 
// 
//     /**
//      * @param entityManager JPA entity manager reference.
//      * @param work Work to execute passing in the underlying JDBC connection object.
//      * @return the output of the work.
//      */
//     public <R> R exec(EntityManager entityManager, Function<Connection, R> work);
// }


import org.hibernate.persister.entity.SingleTableEntityPersister;
import com.eclecticlogic.pedal.provider.Consumer;
import com.eclecticlogic.pedal.provider.Function;
import com.eclecticlogic.pedal.provider.ProviderAccessSpi;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.metadata.ClassMetadata;
     * @param entityClass Entity class for which the table name is required.
     * @return Table name if the entity class is a single table.
     */
    @Override
    public String getTableName(Class<? extends Serializable> entityClass) {
        SessionFactory sf = emf.unwrap(HibernateEntityManagerFactory.class).getSessionFactory();
        ClassMetadata metadata = sf.getClassMetadata(entityClass);
        if (metadata instanceof SingleTableEntityPersister) {
            SingleTableEntityPersister step = (SingleTableEntityPersister) metadata;
            return step.getTableName();
        } else {
            return null;
        }
    }


    @Override
    public void run(EntityManager entityManager, final Consumer<Connection> work) {
        Session session = entityManager.unwrap(Session.class);
        session.doWork(new Work() {

            @Override
            public void execute(Connection connection) throws SQLException {
                work.accept(connection);
            }
        });
    }


    @Override
// Path: src/main/java/com/eclecticlogic/pedal/provider/Consumer.java
// public interface Consumer<T> {
//     
//     
//     void accept(T value);
// 
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/provider/Function.java
// public interface Function<T, R> {
// 
//     R apply(T value);
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/provider/ProviderAccessSpi.java
// public interface ProviderAccessSpi extends ProviderAccess {
// 
//     /**
//      * @param entityMangager JPA entity manager reference.
//      * @param work Execute the work passing in the underlying JDBC connection object.
//      */
//     public void run(EntityManager entityManager, Consumer<Connection> work);
// 
// 
//     /**
//      * @param entityManager JPA entity manager reference.
//      * @param work Work to execute passing in the underlying JDBC connection object.
//      * @return the output of the work.
//      */
//     public <R> R exec(EntityManager entityManager, Function<Connection, R> work);
// }


// Path: src/main/java/com/eclecticlogic/pedal/provider/hibernate/HibernateProviderAccessSpiImpl.java
import org.hibernate.persister.entity.SingleTableEntityPersister;
import com.eclecticlogic.pedal.provider.Consumer;
import com.eclecticlogic.pedal.provider.Function;
import com.eclecticlogic.pedal.provider.ProviderAccessSpi;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.metadata.ClassMetadata;

     * @param entityClass Entity class for which the table name is required.
     * @return Table name if the entity class is a single table.
     */
    @Override
    public String getTableName(Class<? extends Serializable> entityClass) {
        SessionFactory sf = emf.unwrap(HibernateEntityManagerFactory.class).getSessionFactory();
        ClassMetadata metadata = sf.getClassMetadata(entityClass);
        if (metadata instanceof SingleTableEntityPersister) {
            SingleTableEntityPersister step = (SingleTableEntityPersister) metadata;
            return step.getTableName();
        } else {
            return null;
        }
    }


    @Override
    public void run(EntityManager entityManager, final Consumer<Connection> work) {
        Session session = entityManager.unwrap(Session.class);
        session.doWork(new Work() {

            @Override
            public void execute(Connection connection) throws SQLException {
                work.accept(connection);
            }
        });
    }


    @Override
    public <R> R exec(EntityManager entityManager, final Function<Connection, R> work) {