Can UnitOfWorkInvoker just use Dropwizard's UnitOfWorkAspect? #91
Replies: 3 comments
-
After some initial investigation this will cause some API changes, because we need to create a // initialization, most likely in a constructor
this.unitOfWorkAwareProxyFactory = new UnitOfWorkAwareProxyFactory(hibernateBundle);
// in method(s) that require the aspect
// this also requires the UnitOfWork annotation
var aspect = unitOfWorkAwareProxyFactory.newAspect();
try {
aspect.beforeStart(unitOfWork);
var result = performBusinessOperation(); // custom logic
aspect.afterEnd();
return result;
} catch (Exception e) {
aspect.onError();
throw e;
} finally {
aspect.onFinish();
} So, the This change will ripple out to the UnitOfWorkInvokerFactory#create method, which will also need to supply a This ends up with two separate public API changes, which will necessitate a major version bump. |
Beta Was this translation helpful? Give feedback.
-
And of course we should create some kind of utility to avoid writing all that aspect boilerplate every time it's needed. For example: import io.dropwizard.hibernate.UnitOfWork;
import io.dropwizard.hibernate.UnitOfWorkAspect;
import lombok.experimental.UtilityClass;
import java.util.function.Supplier;
@UtilityClass
class UnitOfWorkAspects {
static <T> T getWithAspect(UnitOfWorkAspect aspect,
UnitOfWork unitOfWork,
Supplier<T> supplier) {
try {
aspect.beforeStart(unitOfWork);
var result = supplier.get();
aspect.afterEnd();
return result;
} catch (Exception e) {
aspect.onError();
throw e;
} finally {
aspect.onFinish();
}
}
} This could be a candidate for kiwi. |
Beta Was this translation helpful? Give feedback.
-
Here is a rough draft implementation of a new package org.kiwiproject.dropwizard.jakarta.xml.ws;
import static java.util.Objects.requireNonNull;
import io.dropwizard.core.Configuration;
import io.dropwizard.hibernate.HibernateBundle;
import io.dropwizard.hibernate.UnitOfWork;
import io.dropwizard.hibernate.UnitOfWorkAwareProxyFactory;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.service.invoker.Invoker;
import java.util.Map;
/**
* Wraps underlying invoker in a Hibernate session.
*
* @see io.dropwizard.hibernate.UnitOfWorkAspect
* @see io.dropwizard.hibernate.UnitOfWorkAwareProxyFactory
*/
public class UnitOfWorkInvoker extends AbstractInvoker {
private final UnitOfWorkAwareProxyFactory unitOfWorkAwareProxyFactory;
private final Map<String, UnitOfWork> unitOfWorkMethods;
public <C extends Configuration> UnitOfWorkInvoker(Invoker underlying,
Map<String, UnitOfWork> unitOfWorkMethods,
HibernateBundle<C> hibernateBundle) {
super(underlying);
this.unitOfWorkMethods = Map.copyOf(unitOfWorkMethods);
this.unitOfWorkAwareProxyFactory = new UnitOfWorkAwareProxyFactory(hibernateBundle);
}
@Override
public Object invoke(Exchange exchange, Object o) {
var methodName = this.getTargetMethod(exchange).getName();
if (unitOfWorkMethods.containsKey(methodName)) {
var unitOfWork = requireNonNull(unitOfWorkMethods.get(methodName));
var aspect = unitOfWorkAwareProxyFactory.newAspect();
return UnitOfWorkAspects.getWithAspect(aspect,
unitOfWork,
() -> underlying.invoke(exchange, o));
} else {
return underlying.invoke(exchange, o);
}
}
} |
Beta Was this translation helpful? Give feedback.
-
When
UnitOfWorkInvoker
was originally implemented in 2013, theUnitOfWorkAspect
was package-private. This is why the javadoc says:The javadocs also state:
However,
UnitOfWorkAspect
was made public in 2016 and released in Dropwizard version 1.1.0.So,
UnitOfWorkInvoker
can now useUnitOfWorkAspect
which would simplify the code, take advantage of improvements made to it by the Dropwizard team, and this library no longer needs to worry about keeping it up-to-date withUnitOfWorkAspect
(which it isn't).Beta Was this translation helpful? Give feedback.
All reactions