Skip to content

Commit cfd4089

Browse files
committed
@transactional is now in core, add support for jooby-jdbi.
1 parent 5440552 commit cfd4089

4 files changed

Lines changed: 67 additions & 30 deletions

File tree

‎jooby/src/main/java/io/jooby/Context.java‎

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

8+
import io.jooby.annotations.Transactional;
89
import io.jooby.internal.ReadOnlyContext;
910
import io.jooby.internal.WebSocketSender;
1011

@@ -1283,6 +1284,33 @@ public interface Context extends Registry {
12831284
*/
12841285
@Nonnull Context onComplete(@Nonnull Route.Complete task);
12851286

1287+
/* **********************************************************************************************
1288+
* Default methods
1289+
* **********************************************************************************************
1290+
*/
1291+
1292+
/**
1293+
* Returns whether the matched route is marked as transactional, or returns
1294+
* {@code defaultValue} if the route has not been marked explicitly.
1295+
*
1296+
* @param defaultValue the value to return if the route was not explicitly marked
1297+
* @return whether the route should be considered as transactional
1298+
*/
1299+
default boolean isTransactional(boolean defaultValue) {
1300+
Object attribute = getRoute().attribute(Transactional.ATTRIBUTE);
1301+
1302+
if (attribute == null) {
1303+
return defaultValue;
1304+
}
1305+
1306+
if (attribute instanceof Boolean) {
1307+
return (Boolean) attribute;
1308+
}
1309+
1310+
throw new RuntimeException("Invalid value for route attribute "
1311+
+ Transactional.ATTRIBUTE + ": " + attribute);
1312+
}
1313+
12861314
/* **********************************************************************************************
12871315
* Factory methods
12881316
* **********************************************************************************************

modules/jooby-hibernate/src/main/java/io/jooby/hibernate/Transactional.java renamed to jooby/src/main/java/io/jooby/annotations/Transactional.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
44
* Copyright 2014 Edgar Espina
55
*/
6-
package io.jooby.hibernate;
6+
package io.jooby.annotations;
77

88
import java.lang.annotation.ElementType;
99
import java.lang.annotation.Retention;
1010
import java.lang.annotation.RetentionPolicy;
1111
import java.lang.annotation.Target;
1212

1313
/**
14-
* Useful together with the {@link TransactionalRequest} route decorator to
15-
* toggle it's effect for a single route.
14+
* Useful together with the various route decorators like {@code TransactionalRequest}
15+
* provided by extensions {@code jooby-hibernate} or {@code jooby-jdbi} to toggle it's
16+
* effect for a single route.
1617
* <p>
17-
* Although {@link TransactionalRequest} is configured to be enabled by default,
18+
* Although {@code TransactionalRequest} is configured to be enabled by default,
1819
* for a route method annotated with {@code @Transactional(false)} it won't take effect.
1920
* <p>
2021
* Similarly, if the decorator is disabled by default, a for route method annotated with
@@ -27,16 +28,16 @@
2728
* }
2829
* }</pre>
2930
* <p>
30-
* This annotation has no effect on the behavior of the {@link SessionRequest} decorator.
31+
* This annotation has no effect on the behavior of {@code SessionRequest} decorator(s).
3132
*/
3233
@Target(ElementType.METHOD)
3334
@Retention(RetentionPolicy.RUNTIME)
3435
public @interface Transactional {
3536

3637
/**
37-
* Whether to enable or disable {@link TransactionalRequest} for the annotated route.
38+
* Whether to enable or disable {@code TransactionalRequest} for the annotated route.
3839
*
39-
* @return value to toggle {@link TransactionalRequest}
40+
* @return value to toggle {@code TransactionalRequest}
4041
*/
4142
boolean value() default true;
4243

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

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
*/
66
package io.jooby.hibernate;
77

8-
import io.jooby.Context;
98
import io.jooby.Route;
109
import io.jooby.ServiceKey;
1110
import io.jooby.SneakyThrows;
11+
import io.jooby.annotations.Transactional;
1212
import org.hibernate.Session;
1313
import org.hibernate.SessionFactory;
1414
import org.hibernate.Transaction;
@@ -97,7 +97,7 @@ public TransactionalRequest enabledByDefault(boolean enabledByDefault) {
9797

9898
@Nonnull @Override public Route.Handler apply(@Nonnull Route.Handler next) {
9999
return sessionRequest.apply(ctx -> {
100-
if (isTransactional(ctx)) {
100+
if (ctx.isTransactional(enabledByDefault)) {
101101
SessionFactory sessionFactory = ctx.require(sessionRequest.getSessionFactoryKey());
102102
Transaction trx = null;
103103
try {
@@ -123,19 +123,4 @@ public TransactionalRequest enabledByDefault(boolean enabledByDefault) {
123123
}
124124
});
125125
}
126-
127-
private boolean isTransactional(Context context) {
128-
Object attribute = context.getRoute().attribute(Transactional.ATTRIBUTE);
129-
130-
if (attribute == null) {
131-
return enabledByDefault;
132-
}
133-
134-
if (!(attribute instanceof Boolean)) {
135-
throw new RuntimeException("Invalid value for route attribute "
136-
+ Transactional.ATTRIBUTE + ": " + attribute);
137-
}
138-
139-
return (Boolean) attribute;
140-
}
141126
}

‎modules/jooby-jdbi/src/main/java/io/jooby/jdbi/TransactionalRequest.java‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.jooby.Route.Decorator;
1010
import io.jooby.ServiceKey;
1111
import io.jooby.RequestScope;
12+
import io.jooby.annotations.Transactional;
1213
import org.jdbi.v3.core.Handle;
1314
import org.jdbi.v3.core.Jdbi;
1415

@@ -69,6 +70,8 @@ public class TransactionalRequest implements Decorator {
6970

7071
private ServiceKey<Jdbi> key;
7172

73+
private boolean enabledByDefault = true;
74+
7275
/**
7376
* Creates a transactional request. A jdbi with the given name must be available in the service
7477
* registry.
@@ -88,14 +91,34 @@ public TransactionalRequest() {
8891
key = ServiceKey.key(Jdbi.class);
8992
}
9093

94+
/**
95+
* Sets whether all routes in the scope of this decorator instance
96+
* should be transactional or not ({@code true} by default).
97+
* <p>
98+
* You can use the {@link Transactional} annotation to override this
99+
* option on a single route.
100+
*
101+
* @param enabledByDefault whether routes should be transactional by default
102+
* @return this instance
103+
* @see Transactional
104+
*/
105+
public TransactionalRequest enabledByDefault(boolean enabledByDefault) {
106+
this.enabledByDefault = enabledByDefault;
107+
return this;
108+
}
109+
91110
@Nonnull @Override public Route.Handler apply(@Nonnull Route.Handler next) {
92111
return ctx -> {
93-
Jdbi jdbi = ctx.require(key);
94-
try (Handle handle = jdbi.open()) {
95-
RequestScope.bind(jdbi, handle);
96-
return handle.inTransaction(h -> next.apply(ctx));
97-
} finally {
98-
RequestScope.unbind(jdbi);
112+
if (ctx.isTransactional(enabledByDefault)) {
113+
Jdbi jdbi = ctx.require(key);
114+
try (Handle handle = jdbi.open()) {
115+
RequestScope.bind(jdbi, handle);
116+
return handle.inTransaction(h -> next.apply(ctx));
117+
} finally {
118+
RequestScope.unbind(jdbi);
119+
}
120+
} else {
121+
return next.apply(ctx);
99122
}
100123
};
101124
}

0 commit comments

Comments
 (0)