package Ġcom . github . v ok orm Ċ Ċ import Ġcom . zaxxer . hikari . HikariConfig Ċ import Ġcom . zaxxer . hikari . Hikari DataSource Ċ import Ġorg . sql 2 o . Sql 2 o Ċ import Ġorg . sql 2 o . quir ks . Qu ir ks Ċ import Ġorg . sql 2 o . quir ks . Qu ir ks Detector Ċ import Ġjava . io . Closeable Ċ import Ġjavax . sql . DataSource Ċ Ċ /** Ċ Ġ* ĠProvides Ġaccess Ġto Ġa ĠSQL Ġdatabase . ĠBy Ġdefault Ġthe Ġ[ Hikari DataSource Accessor ] Ġis Ġused , Ġbut Ġif Ġyou 're Ġalready Ġusing Ġa Ġcontainer Ċ Ġ* Ġwhich Ġmanages Ġthe Ġtransactions Ġ( e . g . ĠSpring Ġor ĠJava EE ) Ġyou 'll Ġwant Ġa Ġcustom Ġimplementation Ġof Ġthis . Ċ Ġ* Ċ Ġ* ĠClose able Ġ- Ġwill Ġbe Ġclosed Ġwhen Ġ[ V ok Orm . destroy ] Ġis Ġcalled . Ċ Ġ*/ Ċ interface ĠDatabase Accessor Ġ: ĠClose able Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMakes Ġsure Ġgiven Ġblock Ġis Ġexecuted Ġin Ġa ĠDB Ġtransaction . ĠWhen Ġthe Ġblock Ġfinishes Ġnormally , Ġthe Ġtransaction Ġcommits ; ĊĠĠĠĠ Ġ* Ġif Ġthe Ġblock Ġthrows Ġany Ġexception , Ġthe Ġtransaction Ġis Ġrolled Ġback . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠDoes n 't Ġstart Ġnew Ġtransaction Ġif Ġthere Ġalready Ġis Ġtransaction Ġongoing . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ## ĠImplementation Ġinstructions ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠTo Ġobtain Ġthe ĠSql 2 o 's ĠConnection Ġfrom Ġa Ġ[ DataSource ] Ġand Ġthe ĠJDBC ĠURL , Ġyou 'll Ġneed Ġto Ġdo Ġthe Ġfollowing : ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ 1 . ĠObtain Ġthe Ġ[ Qu ir ks ] Ġinstance , Ġeither Ġfrom Ġa ĠJDBC ĠURL Ġ([ Qu ir ks Detector . for URL ]) Ġor Ġfrom Ġthe ĠDataSource Ġitself ĊĠĠĠĠ Ġ* Ġ([ Qu ir ks Detector . for Object ]). ĊĠĠĠĠ Ġ* Ġ 2 . ĠCreate Ġthe Ġ[ Sql 2 o ] Ġinstance : Ġ` Sql 2 o ( dataSource , Ġqu ir ks )` ĊĠĠĠĠ Ġ* Ġ 3 . ĠCall Ġ[ Sql 2 o . open ] Ġto Ġget Ġthe ĠSql 2 o Ġ[ org . sql 2 o . Connection ] Ġwithout Ġdoing Ġany Ġtransaction al Ġmanagement . ĊĠĠĠĠ Ġ* Ġ 4 . ĠPass Ġthe Ġ[ org . sql 2 o . Connection ] Ġto Ġthe Ġconstructor Ġof Ġthe Ġ[ Persistence Context ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġblock Ġthe Ġblock Ġto Ġrun Ġin Ġthe Ġtransaction . ĠBuilder - style Ġprovides Ġhelpful Ġmethods Ġand Ġvalues , Ġe . g . Ġ[ Persistence Context . con ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< R > Ġrun In Transaction ( block : ĠPersistence Context . () Ġ-> ĠR ): ĠR ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġunderlying Ġdata Ġsource Ġused Ġto Ġobtain Ġconnections . ĠThis Ġis Ġoften Ġused Ġby Ġapps Ġto Ġemploy Ġdatabase Ġmigration Ġusing ĠFly way ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval ĠdataSource : ĠDataSource Ċ } Ċ Ċ val ĠH ikariConfig . quir ks : ĠQu ir ks ĊĠĠĠ Ġget () Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġ! jdbc Url . isNull Or Blank () Ġ-> ĠQu ir ks Detector . for URL ( jdbc Url ) ĊĠĠĠĠĠĠĠ ĠdataSource Ġ!= Ġnull Ġ-> ĠQu ir ks Detector . for Object ( dataSource ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" HikariConfig : Ġboth Ġjdbc Url Ġand ĠdataSource Ġis Ġnull ! Ġ$ this ") ĊĠĠĠ Ġ} Ċ Ċ /** Ċ Ġ* ĠAc cesses Ġthe Ġdatabase Ġvia Ġa Ġ[ javax . sql . DataSource ], Ġusing Ġconnection Ġpooling Ġas Ġprovided Ġby ĠH ikari - CP . Ċ Ġ* Ċ Ġ* ĠIt 's Ġimportant Ġto Ġclose Ġthis Ġaccessor Ġproperly , Ġsince Ġthat Ġwill Ġclean Ġup Ġthe Ġconnection Ġpool Ġand Ġclose Ġall ĠJDBC Ġconnections Ġproperly . Ċ Ġ*/ Ċ class ĠH ikari DataSource Accessor ( override Ġval ĠdataSource : ĠH ikari DataSource ) Ġ: ĠDatabase Accessor Ġ{ ĊĠĠĠ Ġprivate Ġval Ġdelegate Ġ= ĠDataSource Accessor ( dataSource , ĠdataSource . quir ks ) ĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġdelegate . close () ĊĠĠĠĠĠĠĠ ĠdataSource . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< R > Ġrun In Transaction ( block : ĠPersistence Context . () Ġ-> ĠR ): ĠR Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelegate . run In Transaction ( block ) Ċ } Ċ Ċ /** Ċ Ġ* ĠAc cesses Ġthe Ġdatabase Ġvia Ġgiven Ġ[ dataSource ]. ĠDoes Ġnot Ġuse Ġany Ġpooling Ġand Ġdoes Ġnot Ġclose Ġthe Ġdata Ġsource . Ċ Ġ* Ġ@ param Ġqu ir ks Ġthe Ġdatabase Ġaccess Ġqu ir ks Ġto Ġuse , Ġdefaults Ġto Ġauto - detected . Ċ Ġ*/ Ċ class ĠDataSource Accessor ( override Ġval ĠdataSource : ĠDataSource , Ġval Ġqu ir ks : ĠQu ir ks Ġ= ĠQu ir ks Detector . for Object ( dataSource )) Ġ: ĠDatabase Accessor Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAuto - detect s Ġqu ir ks Ġfrom Ġgiven Ġ[ jdbc URL ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( dataSource : ĠDataSource , Ġjdbc URL : ĠString ) Ġ: Ġthis ( dataSource , ĠQu ir ks Detector . for URL ( jdbc URL )) ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{} ĊĊĠĠĠ Ġoverride Ġfun Ġ< R > Ġrun In Transaction ( block : ĠPersistence Context . () Ġ-> ĠR ): ĠR Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcontext Ġ= Ġcontexts . get () ĊĠĠĠĠĠĠĠ Ġ// Ġif Ġwe 're Ġalready Ġrunning Ġin Ġa Ġtransaction , Ġjust Ġrun Ġthe Ġblock Ġright Ġaway . ĊĠĠĠĠĠĠĠ Ġif Ġ( context Ġ!= Ġnull ) Ġreturn Ġcontext . block () ĊĊĠĠĠĠĠĠĠ Ġval Ġsql 2 o Ġ= ĠSql 2 o ( dataSource , Ġqu ir ks ) ĊĠĠĠĠĠĠĠ Ġcontext Ġ= ĠPersistence Context ( sql 2 o . beginTransaction ()) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontexts . set ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcontext . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult : ĠR Ġ= Ġcontext . block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . con . commit () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . con . rollback () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( rt : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt . add Sup pressed ( rt ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontexts . set ( null ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠHold s Ġthe Ġ[ Persistence Context ] Ġfor Ġthis Ġthread , Ġso Ġthat Ġwe Ġknow Ġthat Ġa Ġtransaction Ġhas Ġalready Ġbeen Ġstarted Ġin Ġthis Ġthread . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcontexts : ĠThread Local < Persistence Context > Ġ= ĠThread Local () ĊĠĠĠ Ġ} Ċ } Ċ