HHH-18953 Jakarta Data exception translation for reactive repos

This commit is contained in:
Gavin King 2024-12-18 15:11:16 +01:00
parent 4137b0bf91
commit cd9e30dfb3
9 changed files with 143 additions and 110 deletions

View File

@ -185,8 +185,8 @@ else if ( modifiers.contains( Modifier.PROTECTED ) ) {
private static String getFullyQualifiedClassName(Metamodel entity) {
return entity.getElement() instanceof PackageElement packageElement
? packageElement.getQualifiedName().toString() + "." + getGeneratedClassName( entity )
: getGeneratedClassFullyQualifiedName(
(TypeElement) entity.getElement(), entity.getPackageName(), entity.isJakartaDataStyle() );
: getGeneratedClassFullyQualifiedName( (TypeElement) entity.getElement(),
entity.getPackageName(), entity.isJakartaDataStyle() );
}
private static String getGeneratedClassName(Metamodel entity) {

View File

@ -88,4 +88,26 @@ void nullCheck(StringBuilder declaration, String paramName) {
.append(paramName)
.append("\");\n");
}
protected void handle(StringBuilder declaration, String handled, String rethrown) {
if ( isReactive() ) {
declaration.append( "\n\t\t\t.onFailure(" )
.append( annotationMetaEntity.importType( handled ) )
.append( ".class)\n" )
.append( "\t\t\t\t\t.transform((_ex) -> new " )
.append( annotationMetaEntity.importType( rethrown ) )
.append( "(_ex.getMessage(), _ex))" );
}
else {
declaration
.append( "\tcatch (" )
.append( annotationMetaEntity.importType( handled ) )
.append( " _ex) {\n" )
.append( "\t\tthrow new " )
.append( annotationMetaEntity.importType( rethrown ) )
.append( "(_ex.getMessage(), _ex);\n" )
.append( "\t}\n" );
}
}
}

View File

@ -286,34 +286,28 @@ void handlePageParameters(
}
void convertExceptions(StringBuilder declaration) {
if (dataRepository) {
declaration
.append("\t}\n");
if ( singleResult() ) {
if ( dataRepository ) {
if ( !isReactive() ) {
declaration
.append("\tcatch (")
.append(annotationMetaEntity.importType("jakarta.persistence.NoResultException"))
.append(" exception) {\n")
.append("\t\tthrow new ")
.append(annotationMetaEntity.importType("jakarta.data.exceptions.EmptyResultException"))
.append("(exception.getMessage(), exception);\n")
.append("\t}\n")
.append("\tcatch (")
.append(annotationMetaEntity.importType("jakarta.persistence.NonUniqueResultException"))
.append(" exception) {\n")
.append("\t\tthrow new ")
.append(annotationMetaEntity.importType("jakarta.data.exceptions.NonUniqueResultException"))
.append("(exception.getMessage(), exception);\n")
.append("\t}\n");
.append(";\n")
.append( "\t}\n" );
}
if ( singleResult() ) {
handle( declaration, "jakarta.persistence.NoResultException",
"jakarta.data.exceptions.EmptyResultException" );
handle( declaration, "jakarta.persistence.NonUniqueResultException",
"jakarta.data.exceptions.NonUniqueResultException" );
}
handle( declaration, "jakarta.persistence.PersistenceException",
"jakarta.data.exceptions.DataException" );
if ( isReactive() ) {
declaration
.append( ";\n" );
}
}
else {
declaration
.append("\tcatch (")
.append(annotationMetaEntity.importType("jakarta.persistence.PersistenceException"))
.append(" exception) {\n")
.append("\t\tthrow new ")
.append(annotationMetaEntity.importType("jakarta.data.exceptions.DataException"))
.append("(exception.getMessage(), exception);\n")
.append("\t}\n");
.append(";\n");
}
}
@ -392,7 +386,7 @@ void makeKeyedPage(StringBuilder declaration, List<String> paramTypes) {
//SHOULD BE new CursoredPageRecord<>
"\t\treturn new CursoredPageRecord(_results.getResultList(), _cursors, _totalResults, pageRequest,\n" +
"\t\t\t\t_results.isLastPage() ? null : afterCursor(_cursors.get(_cursors.size()-1), pageRequest.page()+1, pageRequest.size(), pageRequest.requestTotal()),\n" +
"\t\t\t\t_results.isFirstPage() ? null : beforeCursor(_cursors.get(0), pageRequest.page()-1, pageRequest.size(), pageRequest.requestTotal()));";
"\t\t\t\t_results.isFirstPage() ? null : beforeCursor(_cursors.get(0), pageRequest.page()-1, pageRequest.size(), pageRequest.requestTotal()))";
static final String MAKE_KEYED_PAGE
= "\tvar _unkeyedPage =\n" +
@ -418,7 +412,7 @@ void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable Str
if ( isJakartaCursoredPage(containerType) ) {
makeKeyedPage( declaration, paramTypes );
}
if ( dataRepository ) {
if ( dataRepository && !isReactive() ) {
declaration
.append("\ttry {\n");
}
@ -430,7 +424,7 @@ void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable Str
}
totalResults(declaration, paramTypes);
}
if ( dataRepository ) {
if ( dataRepository && !isReactive() ) {
declaration
.append('\t');
}
@ -611,11 +605,11 @@ protected void executeSelect(
if ( nullable ) {
unwrapQuery(declaration, unwrapped);
declaration
.append("\t\t\t.getSingleResultOrNull();");
.append("\t\t\t.getSingleResultOrNull()");
}
else {
declaration
.append("\t\t\t.getSingleResult();");
.append("\t\t\t.getSingleResult()");
}
}
else {
@ -628,28 +622,28 @@ protected void executeSelect(
declaration
.append("\t\t\t.getResultList()\n\t\t\t.toArray(new ")
.append(annotationMetaEntity.importType(returnTypeName))
.append("[0]);");
.append("[0])");
}
break;
case OPTIONAL:
unwrapQuery(declaration, unwrapped);
declaration
.append("\t\t\t.uniqueResultOptional();");
.append("\t\t\t.uniqueResultOptional()");
break;
case STREAM:
declaration
.append("\t\t\t.getResultStream();");
.append("\t\t\t.getResultStream()");
break;
case LIST:
declaration
.append("\t\t\t.getResultList();");
.append("\t\t\t.getResultList()");
break;
case HIB_KEYED_RESULT_LIST:
unwrapQuery(declaration, unwrapped);
declaration
.append("\t\t\t.getKeyedResultList(")
.append(parameterName(HIB_KEYED_PAGE, paramTypes, paramNames))
.append(");");
.append(")");
break;
case JD_PAGE:
if ( isReactive() ) {
@ -677,8 +671,6 @@ protected void executeSelect(
declaration
.append(')');
}
declaration
.append(';');
break;
case JD_CURSORED_PAGE:
if ( returnTypeName == null ) {
@ -707,7 +699,7 @@ protected void executeSelect(
declaration
.append("\t\t\t.unwrap(")
.append(annotationMetaEntity.importType(containerType))
.append(".class);");
.append(".class)");
}
else {
@ -715,11 +707,9 @@ protected void executeSelect(
if ( declaration.charAt(lastIndex) == '\n' ) {
declaration.setLength(lastIndex);
}
declaration.append(';');
}
}
}
declaration.append('\n');
}
private static String parameterName(String paramType, List<String> paramTypes, List<String> paramNames) {

View File

@ -77,7 +77,7 @@ String createQueryMethod() {
private void execute(StringBuilder declaration) {
declaration
.append("\t\t\t.executeUpdate();\n");
.append("\t\t\t.executeUpdate()");
}
@Override

View File

@ -89,43 +89,71 @@ private void throwIfNull(StringBuilder declaration) {
.append(')');
}
else if (!nullable) {
declaration
.append(";\n");
if (dataRepository) {
if ( isReactive() ) {
declaration
.append("\t\tif (_result == null) throw new ")
.append(annotationMetaEntity.importType("jakarta.data.exceptions.EmptyResultException"))
.append("(\"No '")
.append(annotationMetaEntity.importType(entity))
.append("' for given id [\" + ")
.append(paramName)
.append(" + \"]\",\n\t\t\t\tnew ")
.append(annotationMetaEntity.importType("org.hibernate.ObjectNotFoundException"))
.append("((Object) ")
.append(paramName)
.append(", \"")
.append(entity)
.append("\"));\n")
.append("\t\treturn _result");
.append( "\n\t\t\t.replaceIfNullWith(() -> { " );
if ( dataRepository ) {
throwEmptyResult( declaration );
}
else {
throwObjectNotFound( declaration );
}
declaration
.append( "; })" );
}
else {
declaration
.append("\tif (_result == null) throw new ")
.append(annotationMetaEntity.importType("org.hibernate.ObjectNotFoundException"))
.append("((Object) ")
.append(paramName)
.append(", \"")
.append(entity)
.append("\");\n")
.append("\treturn _result");
.append( ";\n" );
if ( dataRepository ) {
declaration
.append( "\t\tif (_result == null) " );
throwEmptyResult( declaration );
declaration
.append( ";\n" )
.append( "\t\treturn _result" );
}
else {
declaration
.append( "\tif (_result == null) " );
throwObjectNotFound( declaration );
declaration
.append( ";\n" )
.append( "\treturn _result" );
}
}
}
}
private void throwEmptyResult(StringBuilder declaration) {
declaration
.append(";\n");
.append( "throw new " )
.append( annotationMetaEntity.importType( "jakarta.data.exceptions.EmptyResultException" ) )
.append( "(\"No '" )
.append( annotationMetaEntity.importType( entity ) )
.append( "' for given id [\" + " )
.append( paramName )
.append( " + \"]\",\n\t\t\t\t\tnew " )
.append( annotationMetaEntity.importType( "org.hibernate.ObjectNotFoundException" ) )
.append( "((Object) " )
.append( paramName )
.append( ", \"" )
.append( entity )
.append( "\"))");
}
private void throwObjectNotFound(StringBuilder declaration) {
declaration
.append( "throw new " )
.append( annotationMetaEntity.importType( "org.hibernate.ObjectNotFoundException" ) )
.append( "((Object) " )
.append( paramName )
.append( ", \"" )
.append( entity )
.append( "\")" );
}
private void varOrReturn(StringBuilder declaration) {
if (dataRepository) {
if (dataRepository && !isReactive()) {
declaration
.append("\ttry {\n\t");
}
@ -135,7 +163,7 @@ private void varOrReturn(StringBuilder declaration) {
.append(annotationMetaEntity.staticImport(containerType, "ofNullable"))
.append('(');
}
else if (!nullable) {
else if (!nullable && !isReactive()) {
declaration
.append("\tvar _result = ");
}

View File

@ -57,25 +57,41 @@ public String getAttributeDeclarationString() {
StringBuilder declaration = new StringBuilder();
preamble(declaration);
nullCheck(declaration, parameterName);
declaration.append("\ttry {\n");
if ( !isReactive() ) {
declaration.append( "\ttry {\n" );
}
delegateCall(declaration);
returnArgument(declaration);
declaration.append("\t}\n");
if ( !isReactive() ) {
if ( returnArgument ) {
declaration
.append( ";\n" );
}
declaration.append( "\t}\n" );
}
convertExceptions( declaration );
if ( isReactive() ) {
declaration
.append( ";\n" );
}
declaration.append("}");
return declaration.toString();
}
private void convertExceptions(StringBuilder declaration) {
if ( operationName.equals("insert") ) {
convertException(declaration,
handle( declaration,
"org.hibernate.exception.ConstraintViolationException",
"jakarta.data.exceptions.EntityExistsException");
}
else {
convertException(declaration,
handle( declaration,
"org.hibernate.StaleStateException",
"jakarta.data.exceptions.OptimisticLockingFailureException");
}
convertException(declaration,
handle( declaration,
"jakarta.persistence.PersistenceException",
"jakarta.data.exceptions.DataException");
declaration.append("}");
return declaration.toString();
}
private void returnArgument(StringBuilder declaration) {
@ -91,21 +107,13 @@ private void returnArgument(StringBuilder declaration) {
.append("\t\treturn ")
.append(parameterName);
}
declaration
.append(";\n");
}
else {
if ( isReactive() ) {
declaration
.append(";\n");
}
}
}
private void delegateCall(StringBuilder declaration) {
if ( isReactive() ) {
declaration
.append("\t\treturn ")
.append("\treturn ")
.append(sessionName);
if ( isReactiveSessionAccess() ) {
declaration
@ -188,23 +196,10 @@ private String returnType() {
+ '<' + (returnArgument ? entityType : "Void") + '>';
}
else {
return returnArgument
? entityType
: "void";
return returnArgument ? entityType : "void";
}
}
private void convertException(StringBuilder declaration, String exception, String convertedException) {
declaration
.append("\tcatch (")
.append(annotationMetaEntity.importType(exception))
.append(" exception) {\n")
.append("\t\tthrow new ")
.append(annotationMetaEntity.importType(convertedException))
.append("(exception.getMessage(), exception);\n")
.append("\t}\n");
}
private void notNull(StringBuilder declaration) {
if ( addNonnullAnnotation ) {
declaration

View File

@ -90,11 +90,11 @@ private void findBlockingly(StringBuilder declaration) {
if ( containerType == null ) {
//TODO we should probably throw if this returns null
declaration
.append("\t\t\t.load();\n");
.append("\t\t\t.load()");
}
else {
declaration
.append("\t\t\t.loadOptional();\n");
.append("\t\t\t.loadOptional()");
}
}
@ -143,7 +143,7 @@ private void findReactively(StringBuilder declaration) {
if (composite) {
declaration.append("\n\t\t\t)\n\t");
}
declaration.append(");\n");
declaration.append(')');
}
private boolean isComposite() {

View File

@ -156,8 +156,6 @@ private void execute(StringBuilder declaration, boolean unwrapped) {
declaration
.append(" > 0");
}
declaration
.append(";\n");
}
else {
final boolean mustUnwrap =

View File

@ -56,6 +56,7 @@
import static org.hibernate.processor.util.Constants.ONE_TO_ONE;
import static org.hibernate.processor.util.NullnessUtil.castNonNull;
import static org.hibernate.processor.util.StringUtil.isProperty;
import static org.hibernate.processor.util.StringUtil.removeDollar;
/**
* Utility class.
@ -666,10 +667,9 @@ public static boolean isMemberType(Element element) {
}
public static String getGeneratedClassFullyQualifiedName(TypeElement element, String packageName, boolean jakartaDataStyle) {
final StringBuilder builder = new StringBuilder( !packageName.isEmpty() ? packageName + "." : "" );
final int length = builder.length();
for ( String s : split( ".", element.getQualifiedName().toString().substring( length ) ) ) {
String part = StringUtil.removeDollar( s );
final StringBuilder builder = new StringBuilder( packageName.isEmpty() ? "" : packageName + "." );
for ( String s : split( ".", element.getQualifiedName().toString().substring( builder.length() ) ) ) {
final String part = removeDollar( s );
builder.append( jakartaDataStyle ? '_' + part : part + '_' );
}
return builder.toString();