java - JPA, Hibernate with c3p0 and Postgres. Detect database connectivity issues -
i'm writing application connects postgres db via hibernate c3p0 pooling. before main interface shows i'd detect whatever database connectivity settings valid , connection db possible. if settings not valid i'd show message user , suggest change settings or close application. problem entitymanagerfactory
won't throw exception or return after unsuccessful connection.
here example of code produces error wrong connection settings:
public void connect(connectionsettingsmodel conset) throws exception { map<string, string> connectionproperties = new hashmap<>(); connectionproperties.put("javax.persistence.jdbc.url", conset.geturl()); connectionproperties.put("javax.persistence.jdbc.user", conset.getuser()); connectionproperties.put("javax.persistence.jdbc.password", conset.getpassword()); connectionproperties.put("hibernate.default_schema", conset.getschema()); system.out.println("before creating em"); entitymanagerfactory entitymanagerfactory = persistence.createentitymanagerfactory("postgres-connect", connectionproperties); entitymanager entitymanager = entitymanagerfactory.createentitymanager(); system.out.println("after creating em"); }
c3p0 configuration in persistence.xml
:
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.c3p0connectionprovider"/> <property name="hibernate.c3p0.min_size" value="0"/> <property name="hibernate.c3p0.max_size" value="10"/> <property name="hibernate.c3p0.timeout" value="300"/> <property name="hibernate.c3p0.idle_test_period" value="3000"/> <property name="hibernate.c3p0.max_statements" value="50"/> <property name="hibernate.c3p0.acquireretryattempts" value="1"/>
an log example non existent user name:
before creating em 14:47:07,009 info [com.mchange.v2.log.mlog] - mlog clients using log4j logging. 14:47:07,239 info [com.mchange.v2.c3p0.c3p0registry] - initializing c3p0-0.9.5.2 [built 08-december-2015 22:06:04 -0800; debug? true; trace: 10] 14:47:07,303 info [com.mchange.v2.c3p0.impl.abstractpoolbackeddatasource] - initializing c3p0 pool... com.mchange.v2.c3p0.poolbackeddatasource@e945fe41 [ connectionpooldatasource -> com.mchange.v2.c3p0.wrapperconnectionpooldatasource@d1b84bda [ acquireincrement -> 3, acquireretryattempts -> 1, 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 -> 1hge3hi9nk1ku80noopkx|3185ce3, idleconnectiontestperiod -> 3000, initialpoolsize -> 0, maxadministrativetasktime -> 0, maxconnectionage -> 0, maxidletime -> 300, maxidletimeexcessconnections -> 0, maxpoolsize -> 10, maxstatements -> 50, maxstatementsperconnection -> 0, minpoolsize -> 0, nesteddatasource -> com.mchange.v2.c3p0.drivermanagerdatasource@9480ea7b [ description -> null, driverclass -> null, factoryclasslocation -> null, forceusenameddriverclass -> false, identitytoken -> 1hge3hi9nk1ku80noopkx|26e664, jdbcurl -> jdbc:postgresql://localhost:5432/postgres, properties -> {user=******, password=******} ], preferredtestquery -> null, privilegespawnedthreads -> false, propertycycle -> 0, statementcachenumdeferredclosethreads -> 0, testconnectiononcheckin -> false, testconnectiononcheckout -> false, unreturnedconnectiontimeout -> 0, usestraditionalreflectiveproxies -> false; useroverrides: {} ], datasourcename -> null, extensions -> {}, factoryclasslocation -> null, identitytoken -> 1hge3hi9nk1ku80noopkx|3d02a858, numhelperthreads -> 3 ] квіт. 07, 2017 2:47:07 pm org.postgresql.driver connect severe: connection error: org.postgresql.util.psqlexception: fatal: password authentication failed user "user" --code omitted квіт. 07, 2017 2:47:07 pm org.postgresql.driver connect severe: connection error: org.postgresql.util.psqlexception: fatal: password authentication failed user "user" --code omitted -- few attempts connect 14:47:55,009 warn [com.mchange.v2.resourcepool.basicresourcepool] - having failed acquire resource, com.mchange.v2.resourcepool.basicresourcepool@4519c236 interrupting threads waiting on resource check out. try again in response new client requests.
after message, doesn't throw exception or return
you might consider modifying
<property name="hibernate.c3p0.acquireretryattempts" value="1"/>
back default of 30 (or maybe higher), , try
<property name="hibernate.c3p0.breakafteracquirefailure" value="true"/>
then, if full cycle of attempts acquire connections database fails (again, should more 1 time, or application fragile), c3p0 datasource
break, , further attempts check out connection
fail immediately. downside of you'll lose c3p0's capacity "self-heal" following temporary network or database outage. you'll have reconstruct datasource (or restart application) if temporary outage fails acquisition cycle.
if want best of both worlds, set hibernate.c3p0.acquireretryattempts
30-ish, leave hibernate.c3p0.breakafteracquirefailure
default of false
, write own custom code test availability of database. modifying test connect()
function above (which needs reorganized, want create entitymanagerfactory
once), might simple as...
public void connect(connectionsettingsmodel conset) throws exception { try( connection con = drivermanager.getconnection( conset.geturl(), conset.getuser(), conset.getpassword() ) ) { /* nothing here, really... */ } catch ( exception e ) { system.out.println("trouble connecting dbms, please check database url, username, , password."); throw e; } map<string, string> connectionproperties = new hashmap<>(); connectionproperties.put("javax.persistence.jdbc.url", conset.geturl()); connectionproperties.put("javax.persistence.jdbc.user", conset.getuser()); connectionproperties.put("javax.persistence.jdbc.password", conset.getpassword()); connectionproperties.put("hibernate.default_schema", conset.getschema()); system.out.println("before creating em"); entitymanagerfactory entitymanagerfactory = persistence.createentitymanagerfactory("postgres-connect", connectionproperties); entitymanager entitymanager = entitymanagerfactory.createentitymanager(); system.out.println("after creating em"); }
Comments
Post a Comment