Standalone JPA Example with C3P0 Connection Pool..

.. and H2 Database in Server Mode where Hibernate is the implementation for Java Persistence API!

Make sure you have the file h2-1.4.192.jar somewhere in your computer and start the database in Server mode:
java -jar h2-1.4.192.jar -webAllowOthers -tcpAllowOthers

This is my Directory Layout:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
 
    <groupId>biz.tugay</groupId>
    <artifactId>learningjpa</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <dependencies>
 
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
 
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
 
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
 
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.192</version>
        </dependency>
 
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
 
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
 
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
 
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                                 http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="testdb" transaction-type="RESOURCE_LOCAL">
        <properties/>
    </persistence-unit>
</persistence>

hibernate.properties
hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt
hibernate.connection.username=koraytugay
hibernate.connection.password=koraytugay
hibernate.connection.useUnicode=true
hibernate.connection.characterEncoding=utf-8
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update
 
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=10
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=5
hibernate.c3p0.unreturnedConnectionTimeout=2

PersistenceUtil.java
package biz.tugay.learningjpa;
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 10/16/2016
 * Time: 4:06 PM
 */
public class PersistenceUtil {
 
    private static EntityManagerFactory entityManagerFactory;
 
    private PersistenceUtil() {
        // Do not allow initialization!
    }
 
    public static void openFactory() {
        entityManagerFactory = Persistence.createEntityManagerFactory("testdb");
    }
 
    public static EntityManager getEntityManager() {
        final EntityManager entityManager = entityManagerFactory.createEntityManager();
        return entityManager;
    }
 
    public static void closeFactory() {
        entityManagerFactory.close();
    }
}

MySampleEntity.java
package biz.tugay.learningjpa;
 
import javax.persistence.*;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 10/16/2016
 * Time: 4:08 PM
 */
 
@Entity
@Table(name = "my_sample_entity")
public class MySampleEntity {
 
    private int id;
    private String data;
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    @Basic
    @Column(name = "data")
    public String getData() {
        return data;
    }
 
    public void setData(String data) {
        this.data = data;
    }
}

PersistenceUtilTest.java
package biz.tugay.learningjpa;
 
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
 
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import java.util.ArrayList;
import java.util.List;
 
/**
 * User: Koray Tugay (koray@tugay.biz)
 * Date: 10/16/2016
 * Time: 3:50 PM
 */
public class PersistenceUtilTest {
 
    @Before
    public void init() {
        PersistenceUtil.openFactory();
    }
 
    @After
    public void cleanUp() {
        PersistenceUtil.closeFactory();
    }
 
    @Test
    public void insertEntity() {
        // Given data to be inserted..
        final String data = Long.toString(System.currentTimeMillis());
        final MySampleEntity sampleObject = new MySampleEntity();
        sampleObject.setData(data);
 
        // When data is insterted..
        final EntityManager entityManager = PersistenceUtil.getEntityManager();
        final MySampleEntity insertedEntity = entityManager.merge(sampleObject);
        entityManager.getTransaction().begin();
        entityManager.flush();
        entityManager.getTransaction().commit();
 
        // Then I should be able to find the Entity again..
        final MySampleEntity mySampleEntity = entityManager.find(MySampleEntity.class, insertedEntity.getId());
        Assert.assertTrue(mySampleEntity.getData().equals(data));
 
        // Finally make sure to close the Entity Manager!
        entityManager.close();
    }
 
    @Test(expected = PersistenceException.class)
    public void fooTest() {
        final List<EntityManager> entityManagerList = new ArrayList<EntityManager>();
 
        // Given we request 12 Entity Managers..
        for (int i = 0; i < 12; i++) {
            final EntityManager entityManager = PersistenceUtil.getEntityManager();
            entityManagerList.add(entityManager);
        }
 
        // When all Entity Managers try to begin a transaction
        for (EntityManager entityManager : entityManagerList) {
            entityManager.getTransaction().begin();
        }
        // The first Entity Manager will time out after 2 seconds..
 
        // Then when we try to do an operation with the timeout Entity Manager
        // We expect an Exception!
        final EntityManager entityManager = entityManagerList.get(0);
 
        final MySampleEntity sampleObject = new MySampleEntity();
        sampleObject.setData(Long.toString(System.currentTimeMillis()));
        entityManager.persist(sampleObject);
        entityManager.getTransaction().commit();
        entityManager.close();
 
        // Try changing the value of hibernate.c3p0.max_size to 14 in hibernate.properties
        // And this test will start failing! No Exception will be thrown!
    }
}

Do you want to see the output of maven clean test? Here it is..
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building learningjpa 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ learningjpa ---
[INFO] Deleting C:\Users\Koray Tugay\Desktop\LearningJPA\target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ learningjpa ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ learningjpa ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to C:\Users\Koray Tugay\Desktop\LearningJPA\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ learningjpa ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\Koray Tugay\Desktop\LearningJPA\src\test\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ learningjpa ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to C:\Users\Koray Tugay\Desktop\LearningJPA\target\test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ learningjpa ---
[INFO] Surefire report directory: C:\Users\Koray Tugay\Desktop\LearningJPA\target\surefire-reports
 
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running biz.tugay.learningjpa.PersistenceUtilTest
Oct 16, 2016 7:31:15 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
 name: testdb
 ...]
Oct 16, 2016 7:31:16 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.1.0.Final}
Oct 16, 2016 7:31:16 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000205: Loaded properties from resource hibernate.properties: {hibernate.c3p0.timeout=300, hibernate.connection.driver_class=org.h2.Driver, 
hibernate.c3p0.max_statements=5, hibernate.c3p0.unreturnedConnectionTimeout=2, hibernate.c3p0.max_size=10, 
hibernate.connection.useUnicode=true, hibernate.c3p0.min_size=5, 
hibernate.connection.username=koraytugay, hibernate.hbm2ddl.auto=update, 
hibernate.connection.url=jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt, 
hibernate.bytecode.use_reflection_optimizer=false, hibernate.show_sql=false, hibernate.connection.password=****, hibernate.connection.characterEncoding=utf-8}
Oct 16, 2016 7:31:16 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Oct 16, 2016 7:31:16 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
Oct 16, 2016 7:31:16 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH010002: C3P0 using driver: org.h2.Driver at URL: jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt
Oct 16, 2016 7:31:16 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001001: Connection properties: {useUnicode=true, user=koraytugay, password=****, characterEncoding=utf-8}
Oct 16, 2016 7:31:16 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001003: Autocommit mode: false
Oct 16, 2016 7:31:16 PM com.mchange.v2.log.MLog 
INFO: MLog clients using java 1.4+ standard logging.
Oct 16, 2016 7:31:16 PM com.mchange.v2.c3p0.C3P0Registry 
INFO: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
Oct 16, 2016 7:31:16 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001007: JDBC isolation level: <unknown>
Oct 16, 2016 7:31:16 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@5d4fcdc5 
[ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@9bc32624 
[ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, 
breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, 
connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, 
debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, 
forceSynchronousCheckins -> false, identityToken -> 1hge1dg9j1l9040rwze2n3|12830606, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, 
maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, 
maxPoolSize -> 10, maxStatements -> 5, maxStatementsPerConnection -> 0, minPoolSize -> 5, 
nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@541ea3d9 [ description -> null, driverClass -> null, 
factoryClassLocation -> null, forceUseNamedDriverClass -> false, 
identityToken -> 1hge1dg9j1l9040rwze2n3|7ef30fce, 
jdbcUrl -> jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt, 
properties -> {useUnicode=true, user=******, password=******, characterEncoding=utf-8} ], preferredTestQuery -> null, 
privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, 
testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 2, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], 
dataSourceName -> null, extensions -> {}, factoryClassLocation -> null, identityToken -> 1hge1dg9j1l9040rwze2n3|5587828f, numHelperThreads -> 3 ]
Oct 16, 2016 7:31:16 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@56d39b53
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@5befaa07
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@6bc31e6d
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@5702bd60
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@1d434058
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@446b78ba
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@249a9111
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@2faab9a1
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@6a2e7136
Oct 16, 2016 7:31:19 PM com.mchange.v2.resourcepool.BasicResourcePool 
INFO: A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection@f4bd69f
Oct 16, 2016 7:31:19 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: null
Oct 16, 2016 7:31:19 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: A problem occurred while trying to acquire a cached PreparedStatement in a background thread.
Oct 16, 2016 7:31:19 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
 name: testdb
 ...]
Oct 16, 2016 7:31:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH010002: C3P0 using driver: org.h2.Driver at URL: jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt
Oct 16, 2016 7:31:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001001: Connection properties: {useUnicode=true, user=koraytugay, password=****, characterEncoding=utf-8}
Oct 16, 2016 7:31:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001003: Autocommit mode: false
Oct 16, 2016 7:31:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001007: JDBC isolation level: <unknown>
Oct 16, 2016 7:31:19 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@410c8c40 
[ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@8ab90aff 
[ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, 
automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, 
connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, 
debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, 
forceSynchronousCheckins -> false, identityToken -> 1hge1dg9j1l9040rwze2n3|7de337e3, idleConnectionTestPeriod -> 0, 
initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, 
maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 5, maxStatementsPerConnection -> 0, 
minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@3c7fe263 
[ description -> null, driverClass -> null, factoryClassLocation -> null, forceUseNamedDriverClass -> false, 
identityToken -> 1hge1dg9j1l9040rwze2n3|75fde673, jdbcUrl -> jdbc:h2:tcp://localhost:9092/~/h2dbs/jpadbkt, 
properties -> {useUnicode=true, user=******, password=******, characterEncoding=utf-8} ], 
preferredTestQuery -> null, privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, 
testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 2, 
usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, extensions -> {}, 
factoryClassLocation -> null, identityToken -> 1hge1dg9j1l9040rwze2n3|75e22388, numHelperThreads -> 3 ]
Oct 16, 2016 7:31:19 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.989 sec
 
Results :
 
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.313 s
[INFO] Finished at: 2016-10-16T19:31:19+03:00
[INFO] Final Memory: 15M/219M
[INFO] ------------------------------------------------------------------------
 
Process finished with exit code 0