Skip to content

Commit 75e89ab

Browse files
committed
Hibernate: javadoc/checkstyle
1 parent 6dce35b commit 75e89ab

File tree

2 files changed

+174
-11
lines changed

2 files changed

+174
-11
lines changed

modules/jooby-hibernate/src/main/java/io/jooby/hibernate/HibernateModule.java

Lines changed: 133 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
package io.jooby.hibernate;
77

8-
import com.typesafe.config.Config;
98
import io.jooby.Environment;
109
import io.jooby.Extension;
1110
import io.jooby.Jooby;
@@ -23,6 +22,7 @@
2322
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
2423
import org.hibernate.boot.registry.StandardServiceRegistry;
2524
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
25+
import org.hibernate.cfg.AvailableSettings;
2626

2727
import javax.annotation.Nonnull;
2828
import javax.inject.Provider;
@@ -39,24 +39,146 @@
3939
import java.util.stream.Collectors;
4040
import 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+
*/
44138
public 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()) {

modules/jooby-hibernate/src/main/java/io/jooby/hibernate/TransactionalRequest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,55 @@
1515

1616
import javax.annotation.Nonnull;
1717

18+
/**
19+
* Attach {@link Session} and {@link javax.persistence.EntityManager} to the current request.
20+
* The route pipeline runs inside a transaction which is commit on success or rollback in case of
21+
* exception.
22+
*
23+
* Once route pipeline is executed the session/entityManager is detached from current request and
24+
* closed it.
25+
*
26+
* Usage:
27+
*
28+
* <pre>{@code
29+
* {
30+
*
31+
* install(new HikariModule());
32+
*
33+
* install(new HibernateModule());
34+
*
35+
* decorator(new TransactionalRequest());
36+
*
37+
* get("/handle", ctx -> {
38+
* EntityManager handle = require(EntityManager.class);
39+
* // work with handle.
40+
* });
41+
* }
42+
* }</pre>
43+
*
44+
* NOTE: This is NOT the open session in view pattern. Persistent objects must be fully initialized
45+
* to be encoded/rendered to the client. Otherwise, Hibernate results in
46+
* LazyInitializationException.
47+
*
48+
* @author edgar
49+
* @since 2.0.0
50+
*/
1851
public class TransactionalRequest implements Route.Decorator {
1952

2053
private ServiceKey<SessionFactory> key;
2154

55+
/**
56+
* Creates a new transactional request and attach the to a named session factory.
57+
*
58+
* @param name Name of the session factory.
59+
*/
2260
public TransactionalRequest(@Nonnull String name) {
2361
key = ServiceKey.key(SessionFactory.class, name);
2462
}
2563

64+
/**
65+
* Creates a new transactional request and attach to the default/first session factory registered.
66+
*/
2667
public TransactionalRequest() {
2768
key = ServiceKey.key(SessionFactory.class);
2869
}

0 commit comments

Comments
 (0)