Skip to content

Commit 0070126

Browse files
committed
HHH-18829 Hibernate Processor - representing gnerated ID class as member of parent AnnotationMetaEntity
1 parent 667f1ee commit 0070126

File tree

3 files changed

+105
-27
lines changed

3 files changed

+105
-27
lines changed

tooling/metamodel-generator/src/main/java/org/hibernate/processor/ClassWriter.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import org.hibernate.processor.model.MetaAttribute;
88
import org.hibernate.processor.model.Metamodel;
9-
import org.hibernate.processor.util.Constants;
109

1110
import javax.annotation.processing.FilerException;
1211
import javax.lang.model.element.ElementKind;
@@ -21,9 +20,6 @@
2120
import java.time.format.DateTimeFormatter;
2221
import java.util.List;
2322

24-
import static org.hibernate.processor.util.TypeUtils.hasAnnotation;
25-
import static org.hibernate.processor.util.TypeUtils.isAnnotationMirrorOfType;
26-
2723
/**
2824
* Helper class to write the actual metamodel class using the {@link javax.annotation.processing.Filer} API.
2925
*
@@ -104,8 +100,6 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
104100

105101
pw.println();
106102

107-
generateIdClassIfNeeded( entity, pw );
108-
109103
final List<MetaAttribute> members = entity.getMembers();
110104
for ( MetaAttribute metaMember : members ) {
111105
if ( metaMember.hasStringAttribute() ) {
@@ -236,23 +230,4 @@ private static String writeStaticMetaModelAnnotation(Metamodel entity) {
236230
return "@" + entity.importType( annotation ) + "(" + entity.getSimpleName() + ".class)";
237231
}
238232

239-
private static void generateIdClassIfNeeded(Metamodel entity, PrintWriter pw) {
240-
if ( hasAnnotation( entity.getElement(), Constants.ID_CLASS ) ) {
241-
return;
242-
}
243-
244-
final List<String> idFields = entity.getMembers().stream()
245-
.filter( a -> a.inheritedAnnotations().stream()
246-
.anyMatch( m -> isAnnotationMirrorOfType( m, Constants.ID ) )
247-
)
248-
.map( a -> entity.importType( a.getTypeDeclaration() ) + " " + a.getPropertyName() )
249-
.toList();
250-
251-
if ( idFields.size() > 1 ) {
252-
pw.print( "public record Id(" );
253-
pw.print( String.join( ", ", idFields ) );
254-
pw.println( ") {}" );
255-
pw.println();
256-
}
257-
}
258233
}

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
import java.util.ArrayList;
5656
import java.util.Collection;
5757
import java.util.HashMap;
58-
import java.util.LinkedHashMap;
5958
import java.util.List;
6059
import java.util.Map;
6160
import java.util.Set;
@@ -108,6 +107,8 @@
108107
*/
109108
public class AnnotationMetaEntity extends AnnotationMeta {
110109

110+
private static final String ID_CLASS_MEMBER_NAME = "<ID_CLASS>";
111+
111112
private final ImportContext importContext;
112113
private final TypeElement element;
113114
private final Map<String, MetaAttribute> members;
@@ -168,7 +169,7 @@ public AnnotationMetaEntity(
168169
this.element = element;
169170
this.context = context;
170171
this.managed = managed;
171-
this.members = new LinkedHashMap<>(); // Order should be preserved!
172+
this.members = new HashMap<>();
172173
this.quarkusInjection = context.isQuarkusInjection();
173174
this.importContext = new ImportContextImpl( getPackageName( context, element ) );
174175
jakartaDataStaticModel = jakartaDataStaticMetamodel;
@@ -440,6 +441,8 @@ && containsAnnotation( method, HQL, SQL, FIND ) ) {
440441

441442
addPersistentMembers( fieldsOfClass, AccessType.FIELD );
442443
addPersistentMembers( gettersAndSettersOfClass, AccessType.PROPERTY );
444+
445+
addIdClassIfNeeded( fieldsOfClass, gettersAndSettersOfClass );
443446
}
444447

445448
addAuxiliaryMembers();
@@ -453,6 +456,33 @@ && containsAnnotation( method, HQL, SQL, FIND ) ) {
453456
initialized = true;
454457
}
455458

459+
private void addIdClassIfNeeded(List<? extends Element> fields, List<? extends Element> methods) {
460+
if ( hasAnnotation( element, ID_CLASS ) ) {
461+
return;
462+
}
463+
final List<MetaAttribute> components = new ArrayList<>();
464+
for ( Element field : fields ) {
465+
if ( hasAnnotation( field, ID ) && isPersistent( field, AccessType.FIELD ) ) {
466+
final String propertyName = propertyName( this, field );
467+
if ( members.containsKey( propertyName ) ) {
468+
components.add( members.get( propertyName ) );
469+
}
470+
}
471+
}
472+
for ( Element method : methods ) {
473+
if ( hasAnnotation( method, ID ) && isPersistent( method, AccessType.PROPERTY ) ) {
474+
final String propertyName = propertyName( this, method );
475+
if ( members.containsKey( propertyName ) ) {
476+
components.add( members.get( propertyName ) );
477+
}
478+
}
479+
}
480+
if ( components.size() < 2 ) {
481+
return;
482+
}
483+
putMember( ID_CLASS_MEMBER_NAME, new IdClassMetaAttribute( this, components ) );
484+
}
485+
456486
private boolean checkEntities(List<ExecutableElement> lifecycleMethods) {
457487
boolean foundPersistenceEntity = false;
458488
VariableElement nonPersistenceParameter = null;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.processor.annotation;
6+
7+
import org.hibernate.processor.model.MetaAttribute;
8+
import org.hibernate.processor.model.Metamodel;
9+
10+
import java.util.List;
11+
12+
public class IdClassMetaAttribute implements MetaAttribute {
13+
14+
private final Metamodel parent;
15+
16+
private final List<MetaAttribute> components;
17+
18+
public IdClassMetaAttribute(Metamodel parent, List<MetaAttribute> components) {
19+
this.parent = parent;
20+
this.components = components;
21+
}
22+
23+
@Override
24+
public boolean hasTypedAttribute() {
25+
return true;
26+
}
27+
28+
@Override
29+
public boolean hasStringAttribute() {
30+
return false;
31+
}
32+
33+
@Override
34+
public String getAttributeDeclarationString() {
35+
final StringBuilder decl = new StringBuilder()
36+
.append("\n/**\n * Static ID class for {@link ")
37+
.append( parent.getQualifiedName() )
38+
.append( "}\n **/\n" )
39+
.append( "public record Id" );
40+
String delimiter = "(";
41+
for ( MetaAttribute component : components ) {
42+
decl.append( delimiter ).append( parent.importType( component.getTypeDeclaration() ) )
43+
.append( ' ' ).append( component.getPropertyName() );
44+
delimiter = ", ";
45+
}
46+
return decl.append( ") {}" ).toString();
47+
}
48+
49+
@Override
50+
public String getAttributeNameDeclarationString() {
51+
return "";
52+
}
53+
54+
@Override
55+
public String getMetaType() {
56+
return "";
57+
}
58+
59+
@Override
60+
public String getPropertyName() {
61+
return "";
62+
}
63+
64+
@Override
65+
public String getTypeDeclaration() {
66+
return "";
67+
}
68+
69+
@Override
70+
public Metamodel getHostingEntity() {
71+
return parent;
72+
}
73+
}

0 commit comments

Comments
 (0)