What is the jooby way to solve (or just ideas)?

281 views
Skip to first unread message

Brandon Lamb

unread,
Jul 2, 2017, 1:47:33 PM7/2/17
to jooby-project
I have a microservice with a DB2 and PostgreSQL connection. I am using MyBatis for my db abstraction layer (vs say hibernate, jdbi, etc).

What is the jooby way of setting these up in context of modules or services?

val db2 = require("db1", DataSource::class.java)

val pgsql
= require("db2", DataSource::class.java)


I sort of expected to have code like above, where those two database connections were created with the JDBC module (or myself manually with a hikaricp module). Point being that the "system"/jooby is able to provide jdbc connections.

In addition, I want to provide mybatis my two jdbc connections instead of using the connection pool that comes with mybatis. I thought I would end up with something like below which would be another module?

val sqlSessionFactory = require(SqlSessionFactory::class.java)


However, it seems modules dont have access to Guice or other modules/dependencies? So I am struggling to see how to put the lego pieces together.

In my current Java EE world, I would/could create CDI producers and the producer of the mybatis sqlsessionfactory would be injected with my two resources.

Long story, and I can only assume this is a common problem/pattern that has been solved already. The current documentation was not enough or in-depth enough for me to grok fully the dependency management in jooby. I see some references to serviceKey, and module vs service is fuzzy.

Hopefully this is clear enough, thanks!

Brandon

Edgar Espina

unread,
Jul 2, 2017, 6:53:50 PM7/2/17
to jooby-project
Hi Brandon,

 Very clear. One of the reason there isn't so much documentation about modules is because the heavy dependency on Guice. In order to wire services you need to know Guice. In fact a Jooby module plays the same role as raw/plain Guice module, but of course the Jooby module give you access to the current Env and Configuration and like in a Guice module the services aren't ready yet.

 The jdbc module is kind of special because there are a lot lot of child module who depends on it (hibernate, ebean, jdbi, etc...). Those modules were implemented as subclass of Jdbc at the very beginning of the project, this isn't necessarily wrong but it is kind of limited approach. For example we can't use a full ORM and with jdbi/jooq etc.. due that they all are subclasses of Jdbc :(

  New/latest implementations are more flexible and they do it without subclassing Jdbc. A good example of a "modern" jdbc module is Requery.

  Your MyBatis modules should do something similar to what requery module does. It basically bind the services in Guice and then provision them on application startup. At this phase you can access to external services (datasource here) and do your own bootstrapping.

  Finally, the named require call is implemented using Key object from Guice:
 
binder.bind(Key.get(Datasource.class,Named.names("mydb")).toInstance(ds);

 Later you can do:
val ds= require("mydb",Datasource.class)

 Also have a couple of questions:
  - Did you find any issue with DB2 and the jdbc module?
  - A pull request with a myBatis module could be a good addition

 Hope all this make sense and let me know if you have questions.

Brandon Lamb

unread,
Jul 2, 2017, 9:08:42 PM7/2/17
to jooby-project
Ahhh, okay that makes more sense. I was kind of wondering if maybe Guice was the bigger piece I was missing.

I need to re-read your reply a few more times and I'll check out the Requery module.

If I am able to come up with a clean, re-usable MyBatis module, I will definitely submit a pull-request :)

Great work on this framework!

Brandon Lamb

unread,
Jul 2, 2017, 9:08:42 PM7/2/17
to jooby-project
Replying separately on your other question:

Yes, I was not able to use the Jdbc module with DB2. It complains about url not being a property. If I don't use url and instead pass the database and stuff separately, it then complains about url not being defined, so catch 22.

I did come across the other post here or maybe it was a github issue, but I wasn't able to fully grok what the workaround was.

I *am* able to use hikaricp all by itself though. Once I wrap my head around how to properly approach modules more, maybe I can figure it out.


On Sunday, July 2, 2017 at 3:53:50 PM UTC-7, Edgar Espina wrote:

Brandon Lamb

unread,
Jul 5, 2017, 12:58:55 AM7/5/17
to jooby-project
Here is an initial swag at a HikariCP module


class HikariCP(
internal val name: String,
internal val hikariConfig: HikariConfig = HikariConfig(),
internal val callback: (HikariConfig, Env, Config, Binder) -> Unit = { _, _, _, _ -> }
) : Jooby.Module {
override fun configure(env: Env, config: Config, binder: Binder) {
callback(hikariConfig, env, config, binder)

binder
.bind(Key.get(DataSource::class.java, Names.named(name)))
.toInstance(HikariDataSource(hikariConfig))
}
}

And in my main


use(HikariCP("db2", HikariConfig(), { it, _, config, _ ->
it.jdbcUrl = config.getString("db.db2.jdbcUrl")
it.username = config.getString("db.db2.username")
it.password = config.getString("db.db2.password")
it.maximumPoolSize = config.getInt("db.db2.maximumPoolSize")
it.isAutoCommit = config.getBoolean("db.db2.autoCommit")
it.addDataSourceProperty("driverType", 4)
}))

I'm pretty sure this will let me pass a properties file into the HikariConfig constructor and then possibly override settings in the callback.

I'm not totally sure what all/else the Jdbc module provides, maybe just some auto-configuration stuff? I need to try reading through that source again


On Sunday, July 2, 2017 at 3:53:50 PM UTC-7, Edgar Espina wrote:

Edgar Espina

unread,
Jul 5, 2017, 9:54:52 AM7/5/17
to jooby-project
Looks good and yes the existing jdbc module it is similar.

In theory you can fix the url problem by setting these properties:

db.url = "jdbc:pgsql://localhost:5432/demo"
db.user= myuser
db.password= mypass

## Required while https://github.com/jooby-project/jooby/issues/522 is still open
databases.pgsql.dataSourceClassName = ""
hikari.jdbcUrl = ${db.url}
Reply all
Reply to author
Forward
0 new messages