Skip to content

HHH-19629 Hibernate Processor may fail when repository method parameter has more than one annotation (e.g. multiple constraints) / HHH-19630 Hibernate Processor may fail if the return type is a single entity and annotatated with multiple annotations #10595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.data.constraint;

import org.hibernate.processor.test.util.CompilationTest;
import org.hibernate.processor.test.util.WithClasses;
import org.junit.jupiter.api.Test;

import static org.hibernate.processor.test.util.TestUtil.assertMetamodelClassGeneratedFor;
import static org.hibernate.processor.test.util.TestUtil.getMetaModelSourceAsString;

@CompilationTest
class DataTest {
@Test
@WithClasses({MyEntity.class, MyConstrainedRepository.class})
void test() {
System.out.println( getMetaModelSourceAsString( MyEntity.class ) );
System.out.println( getMetaModelSourceAsString( MyConstrainedRepository.class ) );
assertMetamodelClassGeneratedFor( MyEntity.class );
assertMetamodelClassGeneratedFor( MyConstrainedRepository.class );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.data.constraint;

import jakarta.data.repository.CrudRepository;
import jakarta.data.repository.Find;
import jakarta.data.repository.Repository;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

@Repository
public interface MyConstrainedRepository extends CrudRepository<MyEntity, Long> {

@Valid
@NotNull
@Find
MyEntity findByName(@NotNull @Size(min = 5) String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.data.constraint;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class MyEntity {

@Id
private Long id;
@Column(unique = true)
private String name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import jakarta.persistence.AccessType;
Expand Down Expand Up @@ -2452,7 +2453,7 @@ private void createSingleParameterFinder(
new CriteriaFinderMethod(
this, method,
methodName,
returnType.toString(),
typeAsString( returnType, false ),
containerType,
paramNames,
paramTypes,
Expand Down Expand Up @@ -3388,19 +3389,29 @@ private List<String> parameterTypes(ExecutableElement method) {
* Workaround for a bug in Java 20/21. Should not be necessary!
*/
private String typeAsString(TypeMirror type) {
String result = type.toString();
for ( AnnotationMirror annotation : type.getAnnotationMirrors() ) {
final String annotationString = annotation.toString();
result = result
// if it has a space after it, we need to remove that too
.replace(annotationString + ' ', "")
// just in case it did not have a space after it
.replace(annotationString, "");
}
for ( AnnotationMirror annotation : type.getAnnotationMirrors() ) {
result = annotation.toString() + ' ' + result;
return typeAsString( type, true );
}

private String typeAsString(TypeMirror type, boolean includeAnnotations) {
if ( type instanceof DeclaredType dt && dt.asElement() instanceof TypeElement te ) {
// get the "fqcn" without any type arguments
String result = te.getQualifiedName().toString();
// add the < ? ,? ....> as necessary:
if ( !dt.getTypeArguments().isEmpty() ) {
result += dt.getTypeArguments().stream()
.map( arg -> typeAsString( arg, true ) )
.collect( Collectors.joining( ", ", "<", ">" ) );
}
if ( includeAnnotations ) {
for ( AnnotationMirror annotation : type.getAnnotationMirrors() ) {
result = annotation.toString() + ' ' + result;
}
}
return result;
}
else {
return type.toString();
}
return result;
}

private TypeMirror parameterType(VariableElement parameter) {
Expand Down