Ability to configure the Session in jooby-hbm

19 views
Skip to first unread message

István Mészáros

unread,
Sep 25, 2019, 5:50:06 AM9/25/19
to jooby-project
In our project we need to wire-in a session scoped hibernate interceptor. As far as i know this is currently not possible with jooby-hbm, since it must be done using SessionFactory.withOptions().<your config calls here like .interceptor(...) >.openSession(), and jooby-hbm's SessionProvider and UnitOfWorkProvider directly calls to SessionFactory.openSession().

My current workaround is to reimplement the Hbm, SessionProvider, UnitOfWorkProvider classes:

Hbm:

public class HbmPatch implements Jooby.Module {

...

private BiConsumer<SessionBuilder, Config> sb = NOOP;

...

public <T> HbmPatch doWithSessionBuilder(
final BiConsumer<SessionBuilder, Config> configurer) {
this.sb = configurer;
return this;
}

public <T> HbmPatch doWithSessionBuilder(final Consumer<SessionBuilder> configurer) {
return doWithSessionBuilder((builder, conf) -> configurer.accept(builder));
}

@Override
public void configure(final Env env, final Config conf, final Binder binder) {

...

Function<SessionFactory, Session> sp = sf -> {
final SessionBuilder builder = sf.withOptions();
sb.accept(builder, conf);
return builder.openSession();
};

Provider<Session> session = new SessionProviderPatch(sessionFactory, sp);

...

/** Unit of work . */
Provider<UnitOfWork> uow = new UnitOfWorkProviderPatch(sessionFactory, sp);

...
}
}




SessionProvider:

public class SessionProviderPatch implements Provider<Session> {

private final SessionFactory sf;
private final Function<SessionFactory, Session> sp;

public SessionProviderPatch(final SessionFactory sf, final Function<SessionFactory, Session> sp) {
this.sf = sf;
this.sp = sp;
}

@Override
public Session get() {
return ManagedSessionContext.hasBind(sf) ? sf.getCurrentSession() : sp.apply(sf);
}
}

UnitOfWorkProvider:

public class UnitOfWorkProviderPatch implements Provider<UnitOfWork> {

private final SessionFactory sf;
private final Function<SessionFactory, Session> sp;

public UnitOfWorkProviderPatch(final SessionFactory sf, final Function<SessionFactory, Session> sp) {
this.sf = sf;
this.sp = sp;
}

@Override
public UnitOfWork get() {
if (ManagedSessionContext.hasBind(sf)) {
return new ChildUnitOfWork(sf.getCurrentSession());
} else {
return new RootUnitOfWork(sp.apply(sf));
}
}
}


What do you think? May I make a PR for this, or is there another preferred way to do this?

István Mészáros

unread,
Sep 25, 2019, 5:52:03 AM9/25/19
to jooby-project
Example use case:

use(new HbmPatch("db")
.doWithSessionBuilder(b -> b.interceptor(new ActionLogInterceptor(require(ActionLogManager.class))))
.scan("my.package"));


Reply all
Reply to author
Forward
0 new messages