Skip to content
Merged
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
Expand Up @@ -14,6 +14,9 @@
* @see jakarta.persistence.Version
*/
public interface EntityVersionMapping extends BasicValuedModelPart {

String VERSION_ROLE_NAME = "{version}";

/**
* The attribute marked as the version
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public interface BookAuthorRepository {
Book book(String isbn);

@Find
Optional<Book> bookMaybe(@By("#id") String id);
Optional<Book> bookMaybe(@By("id(this)") String id);

@Find
Book[] books(@By("isbn") String[] isbns);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ public class CompositeIdClassTest extends CompilationTest {
@Test
@WithClasses({
MyRepository.class,
YourRepository.class,
MyEntity.class,
})
public void test() {
System.out.println( getMetaModelSourceAsString( MyEntity.class ) );
System.out.println( getMetaModelSourceAsString( MyEntity.class, true ) );
System.out.println( getMetaModelSourceAsString( MyRepository.class ) );
System.out.println( getMetaModelSourceAsString( YourRepository.class ) );
assertMetamodelClassGeneratedFor( MyEntity.class );
assertMetamodelClassGeneratedFor( MyEntity.class, true );
assertMetamodelClassGeneratedFor( MyRepository.class );
assertMetamodelClassGeneratedFor( YourRepository.class );
assertPresenceOfMethodInMetamodelFor(
MyRepository.class,
"findById",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.processor.test.data.idclass;

import jakarta.data.repository.BasicRepository;
import jakarta.data.repository.By;
import jakarta.data.repository.Find;
import jakarta.data.repository.Repository;

import java.util.List;

@Repository
public interface YourRepository
extends BasicRepository<MyEntity, MyEntity.MyEntityId> {
@Find
List<MyEntity> findThem(@By("id(this)") MyEntity.MyEntityId id);
@Find
MyEntity findIt(@By("id(this)") MyEntity.MyEntityId id);

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface SuperRepo<T,K> {
<S extends T> List<S> saveAll(List<S> entities);

@Find
Optional<T> findById(@By("#id") K id);
Optional<T> findById(@By("id(this)") K id);

@Find
Optional<T> findById2(@By("id(this)") K id);
Expand All @@ -37,8 +37,8 @@ public interface SuperRepo<T,K> {
@Find
Page<T> findAll(PageRequest pageRequest, Order<T> order);

// @Delete
// void deleteById(@By("#id") K id);
// @Delete
// void deleteById(@By("id(this)") K id);

@Delete
void delete(T entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static org.hibernate.metamodel.mapping.EntityIdentifierMapping.ID_ROLE_NAME;
import static org.hibernate.processor.util.Constants.ENTITY_MANAGER;
import static org.hibernate.processor.util.Constants.OBJECTS;
import static org.hibernate.processor.util.TypeUtils.hasAnnotation;
Expand Down Expand Up @@ -80,12 +81,18 @@ void nullCheck(StringBuilder declaration, String paramName) {
.append('\t')
.append(annotationMetaEntity.staticImport(OBJECTS, "requireNonNull"))
.append('(')
.append(paramName.replace('.', '$'))
.append(parameterName(paramName))
.append(", \"Null ")
.append(paramName)
.append(ID_ROLE_NAME.equals(paramName) ? "id" : paramName)
.append("\");\n");
}

static String parameterName(String name) {
return name.equals(ID_ROLE_NAME)
? "id"
: name.replace('.', '$');
}

protected void handle(StringBuilder declaration, String handled, String rethrown) {
if ( isReactive() ) {
declaration.append( "\n\t\t\t.onFailure(" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;
import java.util.StringTokenizer;

import static org.hibernate.metamodel.mapping.EntityIdentifierMapping.ID_ROLE_NAME;
import static org.hibernate.processor.util.TypeUtils.getGeneratedClassFullyQualifiedName;
import static org.hibernate.processor.util.TypeUtils.isPrimitive;

Expand Down Expand Up @@ -179,7 +180,7 @@ void where(StringBuilder declaration, List<String> paramTypes) {
private void condition(StringBuilder declaration, int i, String paramName, String paramType) {
declaration
.append("\n\t\t\t");
final String parameterName = paramName.replace('.', '$');
final String parameterName = parameterName(paramName);
if ( isNullable(i) && !isPrimitive(paramType) ) {
declaration
.append(parameterName)
Expand Down Expand Up @@ -226,15 +227,26 @@ private void path(StringBuilder declaration, String paramName) {
final StringTokenizer tokens = new StringTokenizer(paramName, ".");
String typeName = entity;
while ( typeName != null && tokens.hasMoreTokens() ) {
final TypeElement typeElement = annotationMetaEntity.getContext().getElementUtils()
.getTypeElement( typeName );
final TypeElement typeElement =
annotationMetaEntity.getContext().getElementUtils()
.getTypeElement( typeName );
final String memberName = tokens.nextToken();
declaration
.append(".get(")
.append( annotationMetaEntity.importType( getGeneratedClassFullyQualifiedName( typeElement, false ) ) )
.append('.')
.append(memberName)
.append(')');
.append( ".get(" );
if ( ID_ROLE_NAME.equals(memberName) ) {
declaration
.append( '"' )
.append( memberName )
.append( '"' );
}
else {
declaration
.append( annotationMetaEntity.importType(
getGeneratedClassFullyQualifiedName( typeElement, false ) ) )
.append( '.' )
.append( memberName );
}
declaration.append( ')' );
typeName = annotationMetaEntity.getMemberType(typeName, memberName);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javax.lang.model.element.ExecutableElement;
import java.util.List;

import static org.hibernate.metamodel.mapping.EntityIdentifierMapping.ID_ROLE_NAME;
import static org.hibernate.processor.util.Constants.HIB_SESSION;

/**
Expand Down Expand Up @@ -73,8 +74,9 @@ public String getAttributeNameDeclarationString() {
void comment(StringBuilder declaration) {
declaration
.append("\n/**")
.append("\n * Find ")
.append("{@link ")
.append("\n * ")
.append(this instanceof CriteriaDeleteMethod ? "Delete" : "Find")
.append(" {@link ")
.append(annotationMetaEntity.importType(entity))
.append("}");
long paramCount = paramTypes.stream()
Expand All @@ -99,14 +101,20 @@ void comment(StringBuilder declaration) {
}
count++;
final String path = paramNames.get(i);
declaration
.append("{@link ")
.append(annotationMetaEntity.importType(entity))
.append('#')
.append(qualifier(path))
.append(' ')
.append(path)
.append("}");
if ( ID_ROLE_NAME.equals(path) ) {
declaration
.append("identifier");
}
else {
declaration
.append("{@link ")
.append(annotationMetaEntity.importType(entity))
.append('#')
.append(qualifier(path))
.append(' ')
.append(path)
.append("}");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void parameters(List<String> paramTypes, StringBuilder declaration) {
declaration
.append(annotationMetaEntity.importType(paramType))
.append(" ")
.append(paramNames.get(i).replace('.', '$'));
.append(parameterName(paramNames.get(i)));
}
declaration
.append(")");
Expand Down Expand Up @@ -317,8 +317,9 @@ void handleRestrictionParameters(
}
}
else if ( isRangeParam(paramType) && returnTypeName!= null ) {
final TypeElement entityElement = annotationMetaEntity.getContext().getElementUtils()
.getTypeElement( returnTypeName );
final TypeElement entityElement =
annotationMetaEntity.getContext().getElementUtils()
.getTypeElement( returnTypeName );
declaration
.append("\t_spec.restrict(")
.append(annotationMetaEntity.importType(HIB_RESTRICTION))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
import static org.hibernate.grammars.hql.HqlLexer.WHERE;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.internal.util.StringHelper.unqualify;
import static org.hibernate.metamodel.mapping.EntityIdentifierMapping.ID_ROLE_NAME;
import static org.hibernate.processor.annotation.AbstractQueryMethod.isRangeParam;
import static org.hibernate.processor.annotation.AbstractQueryMethod.isRestrictionParam;
import static org.hibernate.processor.annotation.AbstractQueryMethod.isSessionParameter;
Expand Down Expand Up @@ -2271,7 +2272,9 @@ enum FieldType {
}

private @Nullable FieldType validateFinderParameter(TypeElement entityType, VariableElement param) {
final Element member = memberMatchingPath( entityType, parameterName( param ) );
final String path = parameterName( param );
final boolean idClassRef = isIdRef( path ) && hasAnnotation( entityType, ID_CLASS );
final Element member = idClassRef ? null : memberMatchingPath( entityType, path );
if ( member != null ) {
if ( containsAnnotation( member, MANY_TO_MANY, ONE_TO_MANY, ELEMENT_COLLECTION ) ) {
message( param,
Expand Down Expand Up @@ -2302,25 +2305,47 @@ else if ( containsAnnotation( member, NATURAL_ID ) ) {
return FieldType.BASIC;
}
}
else {
else if ( idClassRef ) {
final AnnotationMirror idClass = getAnnotationMirror( entityType, ID_CLASS );
if ( idClass != null ) {
if ( idClass == null ) {
return null; // cannot happen!
}
else {
final AnnotationValue value = getAnnotationValue( idClass );
if ( value != null ) {
if ( isSameType( param.asType(), (TypeMirror) value.getValue() ) ) {
return FieldType.ID;
}
if ( value != null
&& isSameType( actualParameterType( param ),
(TypeMirror) value.getValue() ) ) {
return FieldType.ID;
}
else {
message( param,
"does not match id class of entity class '" + entityType + "'",
Diagnostic.Kind.ERROR );
return null;
}
}

}
else {
message( param,
"no matching field named '" + parameterName( param )
+ "' in entity class '" + entityType + "'",
"no matching field named '" + path
+ "' in entity class '" + entityType + "'",
Diagnostic.Kind.ERROR );
return null;
}
}

private TypeMirror actualParameterType(VariableElement param) {
final ExecutableElement method =
(ExecutableElement)
param.getEnclosingElement();
final ExecutableType methodType =
(ExecutableType)
context.getTypeUtils()
.asMemberOf( (DeclaredType) element.asType(), method );
return methodType.getParameterTypes()
.get( method.getParameters().indexOf( param ) );
}

/**
* Check the type of a parameter of a {@code @Find} method against the field type
* in the entity class.
Expand Down Expand Up @@ -2447,8 +2472,7 @@ private static TypeMirror memberType(Element member) {
}

private static boolean isIdRef(String token) {
return "#id".equals(token) // for Jakarta Data M4 release
|| "id(this)".equalsIgnoreCase(token); // post M4
return "id(this)".equalsIgnoreCase(token); // post M4
}

private @Nullable Element memberMatchingPath(
Expand Down Expand Up @@ -3165,27 +3189,29 @@ private ExecutableType memberMethodType(ExecutableElement method) {
private static List<Boolean> parameterPatterns(ExecutableElement method) {
return method.getParameters().stream()
.map(param -> hasAnnotation(param, PATTERN))
.collect(toList());
.toList();
}

private List<String> parameterNames(ExecutableElement method, TypeElement entity) {
final String idName =
// account for special @By("#id") hack in Jakarta Data
entity.getEnclosedElements().stream()
.filter(member -> hasAnnotation(member, ID))
.map(TypeUtils::propertyName)
.findFirst()
.orElse("id");
hasAnnotation( entity, ID_CLASS )
? ID_ROLE_NAME
// account for special @By("id(this)") hack in Jakarta Data
: entity.getEnclosedElements().stream()
.filter(member -> hasAnnotation(member, ID))
.map(TypeUtils::propertyName)
.findFirst()
.orElse(ID_ROLE_NAME);
return method.getParameters().stream()
.map(AnnotationMetaEntity::parameterName)
.map(name -> isIdRef(name) ? idName : name)
.collect(toList());
.toList();
}

private static List<String> parameterNames(ExecutableElement method) {
return method.getParameters().stream()
.map(AnnotationMetaEntity::parameterName)
.collect(toList());
.toList();
}

private static String parameterName(VariableElement parameter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ private void throwEmptyResult(StringBuilder declaration) {
.append( "(\"No '" )
.append( annotationMetaEntity.importType( entity ) )
.append( "' for given id [\" + " )
.append( paramName )
.append( parameterName(paramName) )
.append( " + \"]\",\n\t\t\t\t\tnew " )
.append( annotationMetaEntity.importType( "org.hibernate.ObjectNotFoundException" ) )
.append( "((Object) " )
.append( paramName )
.append( parameterName(paramName) )
.append( ", \"" )
.append( entity )
.append( "\"))");
Expand Down Expand Up @@ -207,7 +207,7 @@ private void findWithNoFetchProfiles(StringBuilder declaration) {
.append(isUsingStatelessSession() ? ".get(" : ".find(")
.append(annotationMetaEntity.importType(entity))
.append(".class, ")
.append(paramName);
.append(parameterName(paramName));
if ( isReactiveSessionAccess() ) {
declaration
.append(')');
Expand Down
Loading