HHH-16633 use unwrap() in preference to typecasts

perhaps it would be better to preemptively unwrap the
EntityManager to Session, because this approach results
in raw query types (but we don't really care since we
already know it's sound)
This commit is contained in:
Gavin King 2023-07-09 09:44:57 +02:00
parent 9512077462
commit 3dfa70a781
4 changed files with 53 additions and 33 deletions

View File

@ -13,8 +13,6 @@ import org.hibernate.jpamodelgen.util.Constants;
import java.util.List; import java.util.List;
import static org.hibernate.internal.util.StringHelper.join;
/** /**
* @author Gavin King * @author Gavin King
*/ */
@ -60,6 +58,8 @@ public class CriteriaFinderMethod implements MetaAttribute {
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
StringBuilder declaration = new StringBuilder(); StringBuilder declaration = new StringBuilder();
declaration declaration
.append("\n/**\n * @see ") .append("\n/**\n * @see ")
@ -67,7 +67,7 @@ public class CriteriaFinderMethod implements MetaAttribute {
.append("#") .append("#")
.append(methodName) .append(methodName)
.append("(") .append("(")
.append(join(",", paramTypes.stream().map(this::strip).map(annotationMetaEntity::importType).toArray())) .append(parameterList())
.append(")") .append(")")
.append("\n **/\n"); .append("\n **/\n");
if ( belongsToDao ) { if ( belongsToDao ) {
@ -109,7 +109,7 @@ public class CriteriaFinderMethod implements MetaAttribute {
declaration declaration
.append(") {") .append(") {")
.append("\n\tvar builder = entityManager") .append("\n\tvar builder = entityManager")
.append(Constants.ENTITY_MANAGER.equals(sessionType) .append(usingEntityManager
? ".getEntityManagerFactory()" ? ".getEntityManagerFactory()"
: ".getFactory()") : ".getFactory()")
.append(".getCriteriaBuilder();") .append(".getCriteriaBuilder();")
@ -135,27 +135,19 @@ public class CriteriaFinderMethod implements MetaAttribute {
.append(paramNames.get(i)) .append(paramNames.get(i))
.append(")"); .append(")");
} }
declaration declaration
.append("\n\t);") .append("\n\t);")
.append("\n\treturn "); .append("\n\treturn entityManager.createQuery(query)");
if ( containerType != null boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
&& Constants.ENTITY_MANAGER.equals(sessionType) boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate");
&& containerType.startsWith("org.hibernate") ) { boolean unwrap =
( hasEnabledFetchProfiles || hasNativeReturnType )
&& usingEntityManager;
if ( unwrap ) {
declaration declaration
.append("(") .append("\n\t\t\t.unwrap(")
.append(type) .append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
.append(") "); .append(".class)");
}
declaration
.append("entityManager.createQuery(query)");
if ( !fetchProfiles.isEmpty() ) {
if ( Constants.ENTITY_MANAGER.equals(sessionType) ) {
declaration
.append("\n\t\t\t.unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
.append(".class)");
}
} }
for ( String profile : fetchProfiles ) { for ( String profile : fetchProfiles ) {
declaration declaration
@ -163,14 +155,17 @@ public class CriteriaFinderMethod implements MetaAttribute {
.append(profile) .append(profile)
.append(")"); .append(")");
} }
if ( !fetchProfiles.isEmpty() ) {
declaration.append("\n\t\t\t");
}
if ( containerType == null) { if ( containerType == null) {
if ( unwrap || hasEnabledFetchProfiles) {
declaration.append("\n\t\t\t");
}
declaration declaration
.append(".getSingleResult()"); .append(".getSingleResult()");
} }
else if ( containerType.equals(Constants.LIST) ) { else if ( containerType.equals(Constants.LIST) ) {
if ( unwrap || hasEnabledFetchProfiles) {
declaration.append("\n\t\t\t");
}
declaration declaration
.append(".getResultList()"); .append(".getResultList()");
} }
@ -179,6 +174,14 @@ public class CriteriaFinderMethod implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
private String parameterList() {
return paramTypes.stream()
.map(this::strip)
.map(annotationMetaEntity::importType)
.reduce((x, y) -> x + y)
.orElse("");
}
private String strip(String type) { private String strip(String type) {
int index = type.indexOf("<"); int index = type.indexOf("<");
String stripped = index > 0 ? type.substring(0, index) : type; String stripped = index > 0 ? type.substring(0, index) : type;

View File

@ -54,6 +54,8 @@ public class IdFinderMethod implements MetaAttribute {
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
StringBuilder declaration = new StringBuilder(); StringBuilder declaration = new StringBuilder();
declaration declaration
.append("\n/**\n * @see ") .append("\n/**\n * @see ")
@ -99,7 +101,7 @@ public class IdFinderMethod implements MetaAttribute {
.append("\n}"); .append("\n}");
} }
else { else {
if ( Constants.ENTITY_MANAGER.equals(sessionType) ) { if ( usingEntityManager ) {
declaration declaration
.append(".unwrap(") .append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION)) .append(annotationMetaEntity.importType(Constants.HIB_SESSION))

View File

@ -71,6 +71,8 @@ public class QueryMethod implements MetaAttribute {
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
List<String> paramTypes = this.paramTypes.stream() List<String> paramTypes = this.paramTypes.stream()
.map(ptype -> isOrderParam(ptype) && ptype.endsWith("[]") .map(ptype -> isOrderParam(ptype) && ptype.endsWith("[]")
? ptype.substring(0, ptype.length()-2) + "..." ? ptype.substring(0, ptype.length()-2) + "..."
@ -146,11 +148,13 @@ public class QueryMethod implements MetaAttribute {
.append(")") .append(")")
.append(" {") .append(" {")
.append("\n\treturn "); .append("\n\treturn ");
if ( isNative && returnTypeName != null if ( isNative && returnTypeName != null && containerTypeName == null
|| containerTypeName != null && usingEntityManager) {
&& Constants.ENTITY_MANAGER.equals(sessionType) // EntityManager.createNativeQuery() does not return TypedQuery,
&& containerTypeName.startsWith("org.hibernate") ) { // so we need to cast to the entity type
declaration.append("(").append(type).append(") "); declaration.append("(")
.append(type)
.append(") ");
} }
declaration declaration
.append("entityManager.") .append("entityManager.")
@ -164,7 +168,7 @@ public class QueryMethod implements MetaAttribute {
.append(".class"); .append(".class");
} }
declaration.append(")"); declaration.append(")");
boolean unwrapped = !Constants.ENTITY_MANAGER.equals(sessionType); boolean unwrapped = !usingEntityManager;
for (int i = 1; i <= paramNames.size(); i++) { for (int i = 1; i <= paramNames.size(); i++) {
String param = paramNames.get(i-1); String param = paramNames.get(i-1);
String ptype = paramTypes.get(i-1); String ptype = paramTypes.get(i-1);
@ -219,6 +223,17 @@ public class QueryMethod implements MetaAttribute {
declaration declaration
.append("\n\t\t\t.getResultList()"); .append("\n\t\t\t.getResultList()");
} }
else {
if ( usingEntityManager && !unwrapped
&& ( containerTypeName.startsWith("org.hibernate")
|| isNative && returnTypeName != null ) ) {
declaration
.append("\n\t\t\t.unwrap(")
.append(annotationMetaEntity.importType(containerTypeName))
.append(".class)");
}
}
declaration.append(";\n}"); declaration.append(";\n}");
return declaration.toString(); return declaration.toString();
} }

View File

@ -19,7 +19,7 @@ import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassG
public class QueryMethodTest extends CompilationTest { public class QueryMethodTest extends CompilationTest {
@Test @Test
@WithClasses({ Book.class, Dao.class }) @WithClasses({ Book.class, Dao.class })
public void testGeneratedAnnotationNotGenerated() { public void testQueryMethod() {
System.out.println( TestUtil.getMetaModelSourceAsString( Dao.class ) ); System.out.println( TestUtil.getMetaModelSourceAsString( Dao.class ) );
assertMetamodelClassGeneratedFor( Book.class ); assertMetamodelClassGeneratedFor( Book.class );
assertMetamodelClassGeneratedFor( Dao.class ); assertMetamodelClassGeneratedFor( Dao.class );