55 */
66package io .jooby .hibernate ;
77
8- import com .typesafe .config .Config ;
98import io .jooby .Environment ;
109import io .jooby .Extension ;
1110import io .jooby .Jooby ;
2322import org .hibernate .boot .registry .BootstrapServiceRegistryBuilder ;
2423import org .hibernate .boot .registry .StandardServiceRegistry ;
2524import org .hibernate .boot .registry .StandardServiceRegistryBuilder ;
25+ import org .hibernate .cfg .AvailableSettings ;
2626
2727import javax .annotation .Nonnull ;
2828import javax .inject .Provider ;
3939import java .util .stream .Collectors ;
4040import java .util .stream .Stream ;
4141
42- import static org .hibernate .cfg .AvailableSettings .*;
43-
42+ /**
43+ * Hibernate ORM module: https://jooby.io/modules/hibernate.
44+ *
45+ * Usage:
46+ *
47+ * - Add hikari and hibernate dependency
48+ *
49+ * - Install them
50+ *
51+ * <pre>{@code
52+ * {
53+ * install(new HikariModule());
54+ *
55+ * install(new HibernateModule());
56+ * }
57+ * }</pre>
58+ *
59+ * - Use it
60+ *
61+ * <pre>{code
62+ * {
63+ *
64+ * get("/", ctx -> {
65+ * EntityManagerFactory emf = require(EntityManagerFactory.class);
66+ * // do with emf
67+ * });
68+ *
69+ * }
70+ * }</pre>
71+ *
72+ * Optionally, you can require/inject a {@link SessionFactory} too:
73+ *
74+ * <pre>{code
75+ * {
76+ *
77+ * get("/", ctx -> {
78+ * SessionFactory sf = require(SessionFactory.class);
79+ * // do with sf
80+ * });
81+ *
82+ * }
83+ * }</pre>
84+ *
85+ * By default the hibernate module scan the {@link Jooby#getBasePackage()} to register all the
86+ * persistent classes. To scan a different package use the {@link HibernateModule#scan(String...)}
87+ * method.
88+ *
89+ * To turn it off you need to specify all the persistent classes at creation time, using the
90+ * {@link HibernateModule#HibernateModule(Class[])} constructor.
91+ *
92+ * It is important to close either an {@link EntityManager} or {@link Session} created manually
93+ * from {@link javax.persistence.EntityManagerFactory} and {@link SessionFactory}.
94+ *
95+ * So code around session/entityManager looks like:
96+ *
97+ * <pre>{@code
98+ * get("/", ctx -> {
99+ * EntityManager em = require(EntityManager.class);
100+ * Transaction trx = em.getTransaction();
101+ * try {
102+ * trx.begin();
103+ *
104+ * // work with EntityManager compute a result
105+ *
106+ * trx.commit();
107+ *
108+ * return result;
109+ * } catch(Exception x) {
110+ * trx.rollback();
111+ * throw x;
112+ * } finally {
113+ * em.close();
114+ * }
115+ * });
116+ * }</pre>
117+ *
118+ * To avoid all these lines of code we do provide a {@link TransactionalRequest} decorator so code
119+ * looks more simple:
120+ *
121+ * <pre>{@code
122+ * decorator(new TransactionalRequest());
123+ *
124+ * get("/", ctx -> {
125+ * EntityManager em = require(EntityManager.class);
126+ * // work with EntityManager compute a result
127+ * return result;
128+ * });
129+ * }</pre>
130+ *
131+ * Transaction and lifecycle of session/entityManager is managed by {@link TransactionalRequest}.
132+ *
133+ * Complete documentation is available at: https://jooby.io/modules/hibernate.
134+ *
135+ * @author edgar
136+ * @since 2.0.0
137+ */
44138public class HibernateModule implements Extension {
45139
46140 private final String name ;
47141 private List <String > packages = Collections .emptyList ();
48142 private List <Class > classes ;
49143
50- public HibernateModule (@ Nonnull String name , @ Nonnull Class ... classes ) {
144+ /**
145+ * Creates a Hibernate Module. The database parameter can be one of:
146+ *
147+ * - A property key defined in your application configuration file, like <code>db</code>.
148+ * - A special h2 database: mem, local or tmp.
149+ * - A jdbc connection string, like: <code>jdbc:mysql://localhost/db</code>
150+ *
151+ * @param name Database key, database type or jdbc url.
152+ * @param classes Persistent classes.
153+ */
154+ public HibernateModule (@ Nonnull String name , Class ... classes ) {
51155 this .name = name ;
52156 this .classes = Arrays .asList (classes );
53157 }
54158
159+ /**
160+ * Creates a new Hikari module using the <code>db</code> property key. This key must be
161+ * present in the application configuration file, like:
162+ *
163+ * <pre>{@code
164+ * db.url = "jdbc:url"
165+ * db.user = dbuser
166+ * db.password = dbpass
167+ * }</pre>
168+ *
169+ * @param classes Persistent classes.
170+ */
55171 public HibernateModule (Class ... classes ) {
56172 this ("db" , classes );
57173 }
58174
59- public HibernateModule scan (String ... packages ) {
175+ /**
176+ * Scan packages and look for persistent classes.
177+ *
178+ * @param packages Package names.
179+ * @return This module.
180+ */
181+ public @ Nonnull HibernateModule scan (@ Nonnull String ... packages ) {
60182 this .packages = Arrays .asList (packages );
61183 return this ;
62184 }
@@ -72,25 +194,25 @@ public HibernateModule scan(String... packages) {
72194 fallback = true ;
73195 }
74196 BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder ();
75- boolean default_ddl_auto = env .isActive ("dev" , "test" );
197+ boolean defaultDdlAuto = env .isActive ("dev" , "test" );
76198
77199 boolean flyway = isFlywayPresent (env , registry , name , fallback );
78- String ddl_auto = flyway ? "none" : (default_ddl_auto ? "update" : "none" );
200+ String ddlAuto = flyway ? "none" : (defaultDdlAuto ? "update" : "none" );
79201
80202 BootstrapServiceRegistry bsr = bsrb .build ();
81203 StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder (bsr );
82204
83- ssrb .applySetting (HBM2DDL_AUTO , ddl_auto );
84- ssrb .applySetting (CURRENT_SESSION_CONTEXT_CLASS , "managed" );
205+ ssrb .applySetting (AvailableSettings . HBM2DDL_AUTO , ddlAuto );
206+ ssrb .applySetting (AvailableSettings . CURRENT_SESSION_CONTEXT_CLASS , "managed" );
85207 // apply application.conf
86208 Map <String , String > base = env .getProperties ("hibernate" );
87209 Map <String , String > custom = env .getProperties (name + ".hibernate" , "hibernate" );
88210 Map <String , String > settings = new HashMap <>();
89211 settings .putAll (base );
90212 settings .putAll (custom );
91213 ssrb .applySettings (settings );
92- ssrb .applySetting (DATASOURCE , dataSource );
93- ssrb .applySetting (DELAY_CDI_ACCESS , true );
214+ ssrb .applySetting (AvailableSettings . DATASOURCE , dataSource );
215+ ssrb .applySetting (AvailableSettings . DELAY_CDI_ACCESS , true );
94216
95217 StandardServiceRegistry serviceRegistry = ssrb .build ();
96218 if (packages .isEmpty () && classes .isEmpty ()) {
0 commit comments