Remove reading mapping annotations from "Getters" with associated refactoring for performance (#1971)

* #1970 - Change test code only moving mapping annotations to fields

First step in remove support for mapping annotations on "Getters" (so field only target for mapping annotations)

* #1970 - Remove reading mapping annotations from "Getters"

* #1970 - Refactor to use simple annotation lookup where possible

* #1970 - Remove GenerationType.TABLE and SequenceGenerator from type/class

* #1970 - Refactor meta annotation reading

* #1970 - Read @Aggregation as a meta annotation
This commit is contained in:
Rob Bygrave
2020-03-09 16:09:41 +13:00
committed by GitHub
parent 7692d9782a
commit a861e8bdcc
33 changed files with 590 additions and 680 deletions
@@ -23,7 +23,6 @@ import javax.persistence.ManyToOne;
import javax.persistence.PersistenceException;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -53,7 +52,6 @@ public class DeployCreateProperties {
* Create the appropriate properties for a bean.
*/
public void createProperties(DeployBeanDescriptor<?> desc) {
createProperties(desc, desc.getBeanType(), 0);
desc.sortProperties();
}
@@ -89,22 +87,14 @@ public class DeployCreateProperties {
// ignore all fields on model (_$dbName)
return;
}
boolean scalaObject = desc.isScalaObject();
try {
Method[] declaredMethods = beanType.getDeclaredMethods();
Field[] fields = beanType.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (!ignoreField(field)) {
String fieldName = getFieldName(field, beanType);
String initFieldName = initCap(fieldName);
Method getter = findGetter(field, initFieldName, declaredMethods, scalaObject);
DeployBeanProperty prop = createProp(desc, field, beanType, getter);
DeployBeanProperty prop = createProp(desc, field, beanType);
if (prop != null) {
// set a order that gives priority to inherited properties
// push Id/EmbeddedId up and CreatedTimestamp/UpdatedTimestamp down
@@ -137,68 +127,6 @@ public class DeployCreateProperties {
}
}
/**
* Make the first letter of the string upper case.
*/
private String initCap(String str) {
if (str.length() > 1) {
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
} else {
// only a single char
return str.toUpperCase();
}
}
/**
* Return the bean spec field name (trim of "is" from boolean types)
*/
private String getFieldName(Field field, Class<?> beanType) {
String name = field.getName();
if ((Boolean.class.equals(field.getType()) || boolean.class.equals(field.getType()))
&& name.startsWith("is") && name.length() > 2) {
// it is a boolean type field starting with "is"
char c = name.charAt(2);
if (Character.isUpperCase(c)) {
String msg = "trimming off 'is' from boolean field name " + name + " in class " + beanType.getName();
logger.info(msg);
return name.substring(2);
}
}
return name;
}
/**
* Find a public non-static getter method that matches this field (according to bean-spec rules).
*/
private Method findGetter(Field field, String initFieldName, Method[] declaredMethods, boolean scalaObject) {
String methGetName = "get" + initFieldName;
String methIsName = "is" + initFieldName;
String scalaGet = field.getName();
for (Method m : declaredMethods) {
if ((scalaObject && m.getName().equals(scalaGet)) || m.getName().equals(methGetName)
|| m.getName().equals(methIsName)) {
Class<?>[] params = m.getParameterTypes();
if (params.length == 0) {
if (field.getType().equals(m.getReturnType())) {
int modifiers = m.getModifiers();
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
// we find it...
return m;
}
}
}
}
}
return null;
}
@SuppressWarnings({"unchecked"})
private DeployBeanProperty createManyType(DeployBeanDescriptor<?> desc, Class<?> targetType, ManyType manyType) {
@@ -218,7 +146,7 @@ public class DeployCreateProperties {
Class<?> propertyType = field.getType();
ManyToOne manyToOne = AnnotationUtil.findAnnotation(field, ManyToOne.class);
ManyToOne manyToOne = AnnotationUtil.get(field, ManyToOne.class);
if (manyToOne != null) {
Class<?> tt = manyToOne.targetEntity();
if (!tt.equals(void.class)) {
@@ -235,8 +163,7 @@ public class DeployCreateProperties {
// List, Set or Map based object
Class<?> targetType = determineTargetType(field);
if (targetType == null) {
Transient transAnnotation = AnnotationUtil.findAnnotation(field, Transient.class);
if (transAnnotation != null) {
if (AnnotationUtil.has(field, Transient.class)) {
// not supporting this field (generic type used)
return null;
}
@@ -271,21 +198,18 @@ public class DeployCreateProperties {
* Return true if the field has one of the special mappings.
*/
private boolean isSpecialScalarType(Field field) {
return (AnnotationUtil.findAnnotation(field, DbJson.class) != null)
|| (AnnotationUtil.findAnnotation(field, DbJsonB.class) != null)
|| (AnnotationUtil.findAnnotation(field, DbArray.class) != null)
|| (AnnotationUtil.findAnnotation(field, DbMap.class) != null)
|| (AnnotationUtil.findAnnotation(field, UnmappedJson.class) != null);
return (AnnotationUtil.has(field, DbJson.class))
|| (AnnotationUtil.has(field, DbJsonB.class))
|| (AnnotationUtil.has(field, DbArray.class))
|| (AnnotationUtil.has(field, DbMap.class))
|| (AnnotationUtil.has(field, UnmappedJson.class));
}
private boolean isTransientField(Field field) {
Transient t = AnnotationUtil.findAnnotation(field, Transient.class);
return (t != null);
return AnnotationUtil.has(field, Transient.class);
}
private DeployBeanProperty createProp(DeployBeanDescriptor<?> desc, Field field, Class<?> beanType, Method getter) {
private DeployBeanProperty createProp(DeployBeanDescriptor<?> desc, Field field, Class<?> beanType) {
DeployBeanProperty prop = createProp(desc, field);
if (prop == null) {
// transient annotation on unsupported type
@@ -293,9 +217,6 @@ public class DeployCreateProperties {
} else {
prop.setOwningType(beanType);
prop.setName(field.getName());
// interested in the getter for reading annotations
prop.setReadMethod(getter);
prop.setField(field);
return prop;
}