experimental support for reactive Jakarta Data repositories

some cleanup

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-03-26 13:08:15 +01:00
parent c5f9ada2fc
commit b4c1b636c5
6 changed files with 109 additions and 105 deletions

View File

@ -0,0 +1,58 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.processor.annotation;
import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSession;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSessionAccess;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingStatelessSession;
import static org.hibernate.processor.util.Constants.ENTITY_MANAGER;
/**
* @author Gavin King
*/
public abstract class AbstractAnnotatedMethod implements MetaAttribute {
final AnnotationMetaEntity annotationMetaEntity;
final String sessionType;
final String sessionName;
public AbstractAnnotatedMethod(AnnotationMetaEntity annotationMetaEntity, String sessionName, String sessionType) {
this.annotationMetaEntity = annotationMetaEntity;
this.sessionName = sessionName;
this.sessionType = sessionType;
}
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
boolean isUsingEntityManager() {
return ENTITY_MANAGER.equals(sessionType);
}
boolean isUsingStatelessSession() {
return usingStatelessSession(sessionType);
}
boolean isReactive() {
return usingReactiveSession(sessionType);
}
boolean isReactiveSessionAccess() {
return usingReactiveSessionAccess(sessionType);
}
String localSessionName() {
return isReactiveSessionAccess() ? "_session" : sessionName;
}
}

View File

@ -8,28 +8,42 @@ package org.hibernate.processor.annotation;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.hibernate.processor.util.Constants.*; import static org.hibernate.processor.util.Constants.BOXED_VOID;
import static org.hibernate.processor.util.Constants.HIB_KEYED_PAGE;
import static org.hibernate.processor.util.Constants.HIB_KEYED_RESULT_LIST;
import static org.hibernate.processor.util.Constants.HIB_ORDER;
import static org.hibernate.processor.util.Constants.HIB_PAGE;
import static org.hibernate.processor.util.Constants.HIB_QUERY;
import static org.hibernate.processor.util.Constants.HIB_SELECTION_QUERY;
import static org.hibernate.processor.util.Constants.HIB_SORT_DIRECTION;
import static org.hibernate.processor.util.Constants.JD_CURSORED_PAGE;
import static org.hibernate.processor.util.Constants.JD_LIMIT;
import static org.hibernate.processor.util.Constants.JD_ORDER;
import static org.hibernate.processor.util.Constants.JD_PAGE;
import static org.hibernate.processor.util.Constants.JD_PAGE_REQUEST;
import static org.hibernate.processor.util.Constants.JD_SORT;
import static org.hibernate.processor.util.Constants.LIST;
import static org.hibernate.processor.util.Constants.OPTIONAL;
import static org.hibernate.processor.util.Constants.QUERY;
import static org.hibernate.processor.util.Constants.SESSION_TYPES;
import static org.hibernate.processor.util.Constants.STREAM;
import static org.hibernate.processor.util.Constants.TYPED_QUERY;
import static org.hibernate.processor.util.TypeUtils.isPrimitive; import static org.hibernate.processor.util.TypeUtils.isPrimitive;
/** /**
* @author Gavin King * @author Gavin King
*/ */
public abstract class AbstractQueryMethod implements MetaAttribute { public abstract class AbstractQueryMethod extends AbstractAnnotatedMethod {
final AnnotationMetaEntity annotationMetaEntity;
final String methodName; final String methodName;
final List<String> paramNames; final List<String> paramNames;
final List<String> paramTypes; final List<String> paramTypes;
final @Nullable String returnTypeName; final @Nullable String returnTypeName;
final String sessionType;
final String sessionName;
final boolean belongsToDao; final boolean belongsToDao;
final List<OrderBy> orderBys; final List<OrderBy> orderBys;
final boolean addNonnullAnnotation; final boolean addNonnullAnnotation;
@ -46,24 +60,17 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
List<OrderBy> orderBys, List<OrderBy> orderBys,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
this.annotationMetaEntity = annotationMetaEntity; super(annotationMetaEntity, sessionName, sessionType);
this.methodName = methodName; this.methodName = methodName;
this.paramNames = paramNames; this.paramNames = paramNames;
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
this.returnTypeName = returnTypeName; this.returnTypeName = returnTypeName;
this.sessionType = sessionType;
this.sessionName = sessionName;
this.belongsToDao = belongsToDao; this.belongsToDao = belongsToDao;
this.orderBys = orderBys; this.orderBys = orderBys;
this.addNonnullAnnotation = addNonnullAnnotation; this.addNonnullAnnotation = addNonnullAnnotation;
this.dataRepository = dataRepository; this.dataRepository = dataRepository;
} }
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
@Override @Override
public String getMetaType() { public String getMetaType() {
throw new UnsupportedOperationException("operation not supported"); throw new UnsupportedOperationException("operation not supported");
@ -175,35 +182,9 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
.append(")"); .append(")");
} }
boolean isUsingEntityManager() {
return ENTITY_MANAGER.equals(sessionType);
}
boolean isUsingStatelessSession() {
return HIB_STATELESS_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
boolean isReactive() {
return MUTINY_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
boolean isReactiveSession() {
return UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
String localSessionName() {
return isReactiveSession() ? "_session" : sessionName;
}
void chainSession(StringBuilder declaration) { void chainSession(StringBuilder declaration) {
// Reactive calls always have a return type // Reactive calls always have a return type
if ( isReactiveSession() ) { if ( isReactiveSessionAccess() ) {
declaration declaration
.append("\treturn ") .append("\treturn ")
.append(sessionName) .append(sessionName)
@ -214,7 +195,7 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
} }
void chainSessionEnd(boolean isUpdate, StringBuilder declaration) { void chainSessionEnd(boolean isUpdate, StringBuilder declaration) {
if ( isReactiveSession() ) { if ( isReactiveSessionAccess() ) {
declaration.append("\t})"); declaration.append("\t})");
// here we're checking for a boxed void and not Uni<Void> because the returnType has already // here we're checking for a boxed void and not Uni<Void> because the returnType has already
// been checked, and is ununi-ed // been checked, and is ununi-ed
@ -463,7 +444,7 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
.append(" _results = "); .append(" _results = ");
} }
else { else {
if ( !"void".equals(returnTypeName) || isReactiveSession() ) { if ( !"void".equals(returnTypeName) || isReactiveSessionAccess() ) {
declaration declaration
.append("return "); .append("return ");
} }

View File

@ -2622,16 +2622,21 @@ public class AnnotationMetaEntity extends AnnotationMeta {
.matcher(hql).matches(); .matcher(hql).matches();
} }
private boolean usingReactiveSession(String sessionType) { static boolean usingReactiveSession(String sessionType) {
return MUTINY_SESSION.equals(sessionType) return MUTINY_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType) || MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_SESSION.equals(sessionType) || UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType); || UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
} }
private boolean usingStatelessSession(String sessionType) { static boolean usingStatelessSession(String sessionType) {
return HIB_STATELESS_SESSION.equals(sessionType) return HIB_STATELESS_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType) || MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType); || UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
} }
static boolean usingReactiveSessionAccess(String sessionType) {
return UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
} }

View File

@ -11,13 +11,12 @@ import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel; import org.hibernate.processor.model.Metamodel;
import org.hibernate.processor.util.Constants; import org.hibernate.processor.util.Constants;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSession;
import static org.hibernate.processor.util.Constants.ENTITY_MANAGER_FACTORY; import static org.hibernate.processor.util.Constants.ENTITY_MANAGER_FACTORY;
import static org.hibernate.processor.util.Constants.HIB_SESSION_FACTORY; import static org.hibernate.processor.util.Constants.HIB_SESSION_FACTORY;
import static org.hibernate.processor.util.Constants.MUTINY_SESSION; import static org.hibernate.processor.util.Constants.MUTINY_SESSION;
import static org.hibernate.processor.util.Constants.MUTINY_SESSION_FACTORY; import static org.hibernate.processor.util.Constants.MUTINY_SESSION_FACTORY;
import static org.hibernate.processor.util.Constants.MUTINY_STATELESS_SESSION; import static org.hibernate.processor.util.Constants.MUTINY_STATELESS_SESSION;
import static org.hibernate.processor.util.Constants.UNI_MUTINY_SESSION;
import static org.hibernate.processor.util.Constants.UNI_MUTINY_STATELESS_SESSION;
/** /**
* Used by the container to instantiate a Jakarta Data repository. * Used by the container to instantiate a Jakarta Data repository.
@ -51,10 +50,7 @@ public class DefaultConstructor implements MetaAttribute {
} }
private boolean isReactive() { private boolean isReactive() {
return MUTINY_SESSION.equals(sessionTypeName) return usingReactiveSession(sessionTypeName);
|| MUTINY_STATELESS_SESSION.equals(sessionTypeName)
|| UNI_MUTINY_SESSION.equals(sessionTypeName)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionTypeName);
} }
@Override @Override

View File

@ -89,7 +89,7 @@ public class IdFinderMethod extends AbstractFinderMethod {
} }
private void findWithNoFetchProfiles(StringBuilder declaration) { private void findWithNoFetchProfiles(StringBuilder declaration) {
if ( isReactiveSession() ) { if ( isReactiveSessionAccess() ) {
declaration declaration
.append(".chain(") .append(".chain(")
.append(localSessionName()) .append(localSessionName())
@ -101,7 +101,7 @@ public class IdFinderMethod extends AbstractFinderMethod {
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class, ") .append(".class, ")
.append(paramName); .append(paramName);
if ( isReactiveSession() ) { if ( isReactiveSessionAccess() ) {
declaration declaration
.append(')'); .append(')');
} }

View File

@ -6,22 +6,12 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel;
import static org.hibernate.processor.util.Constants.MUTINY_SESSION;
import static org.hibernate.processor.util.Constants.MUTINY_STATELESS_SESSION;
import static org.hibernate.processor.util.Constants.UNI; import static org.hibernate.processor.util.Constants.UNI;
import static org.hibernate.processor.util.Constants.UNI_MUTINY_SESSION;
import static org.hibernate.processor.util.Constants.UNI_MUTINY_STATELESS_SESSION;
public class LifecycleMethod implements MetaAttribute { public class LifecycleMethod extends AbstractAnnotatedMethod {
private final AnnotationMetaEntity annotationMetaEntity;
private final String entity; private final String entity;
private final String methodName; private final String methodName;
private final String parameterName; private final String parameterName;
private final String sessionName;
private final String sessionType;
private final String operationName; private final String operationName;
private final boolean addNonnullAnnotation; private final boolean addNonnullAnnotation;
private final boolean iterateParameter; private final boolean iterateParameter;
@ -38,12 +28,10 @@ public class LifecycleMethod implements MetaAttribute {
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean iterateParameter, boolean iterateParameter,
boolean returnArgument) { boolean returnArgument) {
this.annotationMetaEntity = annotationMetaEntity; super(annotationMetaEntity, sessionName, sessionType);
this.entity = entity; this.entity = entity;
this.methodName = methodName; this.methodName = methodName;
this.parameterName = parameterName; this.parameterName = parameterName;
this.sessionName = sessionName;
this.sessionType = sessionType;
this.operationName = operationName; this.operationName = operationName;
this.addNonnullAnnotation = addNonnullAnnotation; this.addNonnullAnnotation = addNonnullAnnotation;
this.iterateParameter = iterateParameter; this.iterateParameter = iterateParameter;
@ -111,30 +99,27 @@ public class LifecycleMethod implements MetaAttribute {
} }
private void delegateCall(StringBuilder declaration) { private void delegateCall(StringBuilder declaration) {
if ( isReactiveSession() ) { if ( isReactive() ) {
declaration declaration
.append("\t\treturn ") .append("\t\treturn ")
.append(sessionName) .append(sessionName);
.append(".chain(") if ( isReactiveSessionAccess() ) {
.append(localSessionName()) declaration
.append(" -> ") .append(".chain(")
.append(localSessionName()) .append(localSessionName())
.append('.') .append(" -> ")
.append(operationName) .append(localSessionName());
.append('(') }
.append(parameterName)
.append(')')
.append(')');
}
else if ( isReactive() ) {
declaration declaration
.append("\t\treturn ")
.append(sessionName)
.append('.') .append('.')
.append(operationName) .append(operationName)
.append('(') .append('(')
.append(parameterName) .append(parameterName)
.append(')'); .append(')');
if ( isReactiveSessionAccess() ) {
declaration
.append(')');
}
} }
else { else {
if ( iterateParameter ) { if ( iterateParameter ) {
@ -236,25 +221,4 @@ public class LifecycleMethod implements MetaAttribute {
public String getTypeDeclaration() { public String getTypeDeclaration() {
return entity; return entity;
} }
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
private boolean isReactive() {
return MUTINY_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
boolean isReactiveSession() {
return UNI_MUTINY_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
}
String localSessionName() {
return isReactiveSession() ? '_' + sessionName : sessionName;
}
} }