diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java index 244efde0b6..316b0a9a03 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java @@ -66,6 +66,7 @@ public final class Context { */ private Boolean fullyXmlConfigured; private boolean addInjectAnnotation = false; + private boolean addNonnullAnnotation = false; private boolean addGeneratedAnnotation = true; private boolean addGenerationDate; private boolean addSuppressWarningsAnnotation; @@ -121,6 +122,14 @@ public final class Context { this.addInjectAnnotation = addInjectAnnotation; } + public boolean addNonnullAnnotation() { + return addNonnullAnnotation; + } + + public void setAddNonnullAnnotation(boolean addNonnullAnnotation) { + this.addNonnullAnnotation = addNonnullAnnotation; + } + public boolean addGeneratedAnnotation() { return addGeneratedAnnotation; } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java index 658d2c6a51..169a1c589b 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java @@ -114,7 +114,13 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { final PackageElement jakartaInjectPackage = context.getProcessingEnvironment().getElementUtils() .getPackageElement( "jakarta.inject" ); + final PackageElement jakartaAnnotationPackage = + context.getProcessingEnvironment().getElementUtils() + .getPackageElement( "jakarta.annotation" ); + context.setAddInjectAnnotation( jakartaInjectPackage != null ); + context.setAddNonnullAnnotation( jakartaAnnotationPackage != null ); + context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null ); final Map options = environment.getOptions(); @@ -122,12 +128,6 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { if ( setting != null ) { context.setAddGeneratedAnnotation( parseBoolean( setting ) ); } - else { - PackageElement jakartaAnnotationPackage = - context.getProcessingEnvironment().getElementUtils() - .getPackageElement( "jakarta.annotation" ); - context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null ); - } context.setAddGenerationDate( parseBoolean( options.get( ADD_GENERATION_DATE ) ) ); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractFinderMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractFinderMethod.java index 6d6d5c41e6..3bb4c63ba3 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractFinderMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractFinderMethod.java @@ -26,6 +26,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute { final boolean belongsToDao; final String sessionType; final boolean usingEntityManager; + private final boolean addNonnullAnnotation; final List fetchProfiles; final List paramNames; @@ -39,7 +40,8 @@ public abstract class AbstractFinderMethod implements MetaAttribute { String sessionType, List fetchProfiles, List paramNames, - List paramTypes) { + List paramTypes, + boolean addNonnullAnnotation) { this.annotationMetaEntity = annotationMetaEntity; this.methodName = methodName; this.entity = entity; @@ -48,7 +50,8 @@ public abstract class AbstractFinderMethod implements MetaAttribute { this.fetchProfiles = fetchProfiles; this.paramNames = paramNames; this.paramTypes = paramTypes; - usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); + this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); + this.addNonnullAnnotation = addNonnullAnnotation; } @Override @@ -81,6 +84,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute { return annotationMetaEntity; } + abstract boolean isId(); @Override public String getAttributeNameDeclarationString() { @@ -123,13 +127,53 @@ public abstract class AbstractFinderMethod implements MetaAttribute { void comment(StringBuilder declaration) { declaration - .append("\n/**\n * @see ") + .append("\n/**") + .append("\n * Find ") + .append("{@link ") + .append(annotationMetaEntity.importType(entity)) + .append("} by "); + int paramCount = paramNames.size(); + for (int i = 0; i < paramCount; i++) { + String param = paramNames.get(i); + if ( i>0 ) { + if ( i + 1 == paramCount) { + declaration + .append(paramCount>2 ? ", and " : " and "); //Oxford comma + } + else { + declaration + .append(", "); + } + } + declaration + .append("{@link ") + .append(annotationMetaEntity.importType(entity)) + .append('#') + .append(param) + .append(' ') + .append(param) + .append("}"); + } + declaration + .append('.') + .append("\n *") + .append("\n * @see ") .append(annotationMetaEntity.getQualifiedName()) .append("#") .append(methodName) .append("(") .append(parameterList()) - .append(")") + .append(")"); +// declaration +// .append("\n *"); +// for (String param : paramNames) { +// declaration +// .append("\n * @see ") +// .append(annotationMetaEntity.importType(entity)) +// .append('#') +// .append(param); +// } + declaration .append("\n **/\n"); } @@ -180,6 +224,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute { declaration .append("("); if ( !belongsToDao ) { + notNull( declaration ); declaration .append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER)) .append(" entityManager"); @@ -189,6 +234,9 @@ public abstract class AbstractFinderMethod implements MetaAttribute { declaration .append(", "); } + if ( isId() ) { + notNull( declaration ); + } declaration .append(annotationMetaEntity.importType(paramTypes.get(i))) .append(" ") @@ -197,4 +245,13 @@ public abstract class AbstractFinderMethod implements MetaAttribute { declaration .append(')'); } + + private void notNull(StringBuilder declaration) { + if ( addNonnullAnnotation ) { + declaration + .append('@') + .append(annotationMetaEntity.importType("jakarta.annotation.Nonnull")) + .append(' '); + } + } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java index 632dba39a6..84dbc1492b 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java @@ -287,7 +287,15 @@ public class AnnotationMetaEntity extends AnnotationMeta { String typeName = element.getSimpleName().toString() + '_'; String sessionType = getterOrSetter.getReturnType().toString(); putMember( name, - new DaoConstructor(this, typeName, name, sessionType, context.addInjectAnnotation() ) ); + new DaoConstructor( + this, + typeName, + name, + sessionType, + context.addInjectAnnotation(), + context.addNonnullAnnotation() + ) + ); return sessionType; } @@ -502,7 +510,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { false, dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); } @@ -541,7 +550,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { paramTypes, dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); } @@ -557,7 +567,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { false, dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); } @@ -582,7 +593,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { parameter.asType().toString(), dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); break; @@ -598,7 +610,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { List.of( parameter.asType().toString() ), dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); break; @@ -615,7 +628,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { fieldType == FieldType.ID, dao, sessionType, - enabledFetchProfiles( method ) + enabledFetchProfiles( method ), + context.addNonnullAnnotation() ) ); break; @@ -703,7 +717,8 @@ public class AnnotationMetaEntity extends AnnotationMeta { paramTypes, isNative, dao, - sessionType + sessionType, + context.addNonnullAnnotation() ); putMember( attribute.getPropertyName() + paramTypes, attribute ); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java index 4cb3507b58..0bb9978798 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java @@ -29,13 +29,19 @@ public class CriteriaFinderMethod extends AbstractFinderMethod { boolean isId, boolean belongsToDao, String sessionType, - List fetchProfiles) { + List fetchProfiles, + boolean addNonnullAnnotation) { super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, - paramNames, paramTypes ); + paramNames, paramTypes, addNonnullAnnotation ); this.containerType = containerType; this.isId = isId; } + @Override + public boolean isId() { + return isId; + } + @Override public String getAttributeDeclarationString() { final StringBuilder declaration = new StringBuilder(); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/DaoConstructor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/DaoConstructor.java index eec12c1945..4240f57c34 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/DaoConstructor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/DaoConstructor.java @@ -19,18 +19,21 @@ public class DaoConstructor implements MetaAttribute { private final String methodName; private final String returnTypeName; private final boolean inject; + private final boolean addNonnullAnnotation; public DaoConstructor( Metamodel annotationMetaEntity, String constructorName, String methodName, String returnTypeName, - boolean inject) { + boolean inject, + boolean addNonnullAnnotation) { this.annotationMetaEntity = annotationMetaEntity; this.constructorName = constructorName; this.methodName = methodName; this.returnTypeName = returnTypeName; this.inject = inject; + this.addNonnullAnnotation = addNonnullAnnotation; } @Override @@ -45,28 +48,44 @@ public class DaoConstructor implements MetaAttribute { @Override public String getAttributeDeclarationString() { - return new StringBuilder() - .append("\nprivate final ") + StringBuilder declaration = new StringBuilder(); + declaration + .append("\nprivate final "); + notNull( declaration ); + declaration .append(annotationMetaEntity.importType(returnTypeName)) .append(" entityManager;") .append("\n") .append(inject ? "\n@" + annotationMetaEntity.importType("jakarta.inject.Inject") : "") .append("\npublic ") .append(constructorName) - .append("(") + .append("("); + notNull( declaration ); + declaration .append(annotationMetaEntity.importType(returnTypeName)) .append(" entityManager) {") .append("\n\tthis.entityManager = entityManager;") .append("\n}") .append("\n\n") - .append("public ") + .append("public "); + notNull( declaration ); + declaration .append(annotationMetaEntity.importType(returnTypeName)) .append(" ") .append(methodName) .append("() {") .append("\n\treturn entityManager;") - .append("\n}") - .toString(); + .append("\n}"); + return declaration.toString(); + } + + private void notNull(StringBuilder declaration) { + if ( addNonnullAnnotation ) { + declaration + .append('@') + .append(annotationMetaEntity.importType("jakarta.annotation.Nonnull")) + .append(' '); + } } @Override diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/IdFinderMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/IdFinderMethod.java index 735ee5eb24..4cbf0e4a70 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/IdFinderMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/IdFinderMethod.java @@ -25,13 +25,19 @@ public class IdFinderMethod extends AbstractFinderMethod { String paramName, String paramType, boolean belongsToDao, String sessionType, - List fetchProfiles) { + List fetchProfiles, + boolean addNonnullAnnotation) { super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, - List.of(paramName), List.of(paramType) ); + List.of(paramName), List.of(paramType), addNonnullAnnotation ); this.paramName = paramName; usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType); } + @Override + boolean isId() { + return true; + } + @Override public String getAttributeDeclarationString() { final StringBuilder declaration = new StringBuilder(); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/NaturalIdFinderMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/NaturalIdFinderMethod.java index 550e235ce5..86cc5c7894 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/NaturalIdFinderMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/NaturalIdFinderMethod.java @@ -21,9 +21,16 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod { List paramNames, List paramTypes, boolean belongsToDao, String sessionType, - List fetchProfiles) { + List fetchProfiles, + boolean addNonnullAnnotation) { super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, - paramNames, paramTypes ); + paramNames, paramTypes, addNonnullAnnotation ); + } + + @Override + boolean isId() { + // natural ids can be null + return false; } @Override diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/QueryMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/QueryMethod.java index 1db157fb4e..598263632f 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/QueryMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/QueryMethod.java @@ -33,6 +33,7 @@ public class QueryMethod implements MetaAttribute { private final boolean isNative; private final boolean belongsToDao; final boolean usingEntityManager; + private final boolean addNonnullAnnotation; public QueryMethod( Metamodel annotationMetaEntity, @@ -46,7 +47,8 @@ public class QueryMethod implements MetaAttribute { List paramTypes, boolean isNative, boolean belongsToDao, - String sessionType) { + String sessionType, + boolean addNonnullAnnotation) { this.annotationMetaEntity = annotationMetaEntity; this.methodName = methodName; this.queryString = queryString; @@ -56,7 +58,8 @@ public class QueryMethod implements MetaAttribute { this.paramTypes = paramTypes; this.isNative = isNative; this.belongsToDao = belongsToDao; - usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); + this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); + this.addNonnullAnnotation = addNonnullAnnotation; } @Override @@ -177,6 +180,7 @@ public class QueryMethod implements MetaAttribute { private void parameters(List paramTypes, StringBuilder declaration) { declaration.append("("); if ( !belongsToDao ) { + notNull( declaration ); declaration .append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER)) .append(" entityManager"); @@ -316,6 +320,15 @@ public class QueryMethod implements MetaAttribute { } } + private void notNull(StringBuilder declaration) { + if ( addNonnullAnnotation ) { + declaration + .append('@') + .append(annotationMetaEntity.importType("jakarta.annotation.Nonnull")) + .append(' '); + } + } + @Override public String getMetaType() { throw new UnsupportedOperationException();