From 0ca5507472cac17b1f4362a683cd401467fdafd3 Mon Sep 17 00:00:00 2001 From: Denis Buzdalov Date: Tue, 24 Jun 2014 18:17:06 +0400 Subject: [PATCH 1/4] A bug of wrong ManyToOne.targetEntity() value interpreting was fixed. --- .../co/jirm/mapper/definition/SqlParameterDefinition.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java index e9f06e4..f1b92b4 100644 --- a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java +++ b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java @@ -15,7 +15,6 @@ */ package co.jirm.mapper.definition; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Strings.isNullOrEmpty; @@ -161,7 +160,11 @@ static SqlParameterDefinition parameterDef( String sn = null; ManyToOne manyToOne = getAnnotation(objectType, parameterName, ManyToOne.class); if (manyToOne != null) { - Class subK = checkNotNull(manyToOne.targetEntity(), "targetEntity not set"); + Class subK = manyToOne.targetEntity(); + if (subK == null || subK.equals(void.class)) { + subK = parameterType; + } + JoinColumn joinColumn = getAnnotation(objectType, parameterName, JoinColumn.class); SqlObjectDefinition od = SqlObjectDefinition.fromClass(subK, config); checkState( ! od.getIdParameters().isEmpty(), "No id parameters"); From 1f2589f285304f73eac4f10b40999c790811a39f Mon Sep 17 00:00:00 2001 From: Denis Buzdalov Date: Thu, 26 Jun 2014 15:11:03 +0400 Subject: [PATCH 2/4] Auto many-to-one determination option was added to the SqlObjectConfig. --- .../java/co/jirm/mapper/SqlObjectConfig.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/jirm-orm/src/main/java/co/jirm/mapper/SqlObjectConfig.java b/jirm-orm/src/main/java/co/jirm/mapper/SqlObjectConfig.java index dc7bc1f..01da12c 100644 --- a/jirm-orm/src/main/java/co/jirm/mapper/SqlObjectConfig.java +++ b/jirm-orm/src/main/java/co/jirm/mapper/SqlObjectConfig.java @@ -34,17 +34,28 @@ public class SqlObjectConfig { private final SqlObjectConverter objectMapper; private final transient Cache, SqlObjectDefinition> cache; private final int maximumLoadDepth = 4; - + private final boolean autoManyToOneDetermination; + + protected SqlObjectConfig( + NamingStrategy namingStrategy, + SqlObjectConverter objectMapper, + SqlParameterConverter converter, + Cache, SqlObjectDefinition> cache) { + this(namingStrategy, objectMapper, converter, cache, false); + } + protected SqlObjectConfig( NamingStrategy namingStrategy, SqlObjectConverter objectMapper, SqlParameterConverter converter, - Cache, SqlObjectDefinition> cache) { + Cache, SqlObjectDefinition> cache, + boolean autoManyToOneDetermination) { super(); this.namingStrategy = namingStrategy; this.converter = converter; this.objectMapper = objectMapper; this.cache = cache; + this.autoManyToOneDetermination = autoManyToOneDetermination; } @@ -72,6 +83,10 @@ public int getMaximumLoadDepth() { public Cache, SqlObjectDefinition> getCache() { return cache; } + + public boolean doAutoDetermineManyToOne() { + return autoManyToOneDetermination; + } public static SqlObjectConfig DEFAULT = new SqlObjectConfig(DefaultNamingStrategy.INSTANCE, From 745ec91a7d4b5d2cc3c8b4ebe0d0c6a8c6c02d47 Mon Sep 17 00:00:00 2001 From: Denis Buzdalov Date: Thu, 26 Jun 2014 15:15:54 +0400 Subject: [PATCH 3/4] COmmon 'sn' variable was moved into the condition branches' code. --- .../java/co/jirm/mapper/definition/SqlParameterDefinition.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java index f1b92b4..c2c6253 100644 --- a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java +++ b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java @@ -157,7 +157,6 @@ static SqlParameterDefinition parameterDef( Class parameterType, int order) { final SqlParameterDefinition definition; - String sn = null; ManyToOne manyToOne = getAnnotation(objectType, parameterName, ManyToOne.class); if (manyToOne != null) { Class subK = manyToOne.targetEntity(); @@ -168,6 +167,7 @@ static SqlParameterDefinition parameterDef( JoinColumn joinColumn = getAnnotation(objectType, parameterName, JoinColumn.class); SqlObjectDefinition od = SqlObjectDefinition.fromClass(subK, config); checkState( ! od.getIdParameters().isEmpty(), "No id parameters"); + String sn = null; if (joinColumn != null) sn = joinColumn.name(); if (sn == null) @@ -185,6 +185,7 @@ static SqlParameterDefinition parameterDef( definition = SqlParameterDefinition.newComplexInstance(config.getConverter(), parameterName, sod, order, sn); } else { + String sn = null; Column col = getAnnotation(objectType, parameterName, Column.class); if (col != null && ! isNullOrEmpty(col.name())) sn = col.name(); From a28857eaaf1e5e6f44467e7e0ac2509988f46145 Mon Sep 17 00:00:00 2001 From: Denis Buzdalov Date: Thu, 26 Jun 2014 15:31:00 +0400 Subject: [PATCH 4/4] Automatic many-to-one determination in case of link to the identifiable object was implemented. --- .../definition/SqlParameterDefinition.java | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java index c2c6253..de7a64b 100644 --- a/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java +++ b/jirm-orm/src/main/java/co/jirm/mapper/definition/SqlParameterDefinition.java @@ -35,6 +35,7 @@ import javax.persistence.Version; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonProperty; import static co.jirm.core.util.JirmPrecondition.check; @@ -144,7 +145,26 @@ static Map getSqlBeanParameters(Class k, SqlO "No SQL columns/parameters found for: {}", k); return parameters; } - + + static boolean isClassComplex(final Class k) { + if (k.isAnnotationPresent(JsonIdentityInfo.class)) { + return true; + } else { + for (final Constructor c : k.getDeclaredConstructors()) { + if (c.isAnnotationPresent(JsonCreator.class)) { + for (final Annotation[] as : c.getParameterAnnotations()) { + for (final Annotation a : as) { + if (JsonProperty.class.equals(a.annotationType())) { + return true; + } + } + } + } + } + + return false; + } + } public Optional getObjectDefinition() { return objectDefinition; @@ -157,22 +177,44 @@ static SqlParameterDefinition parameterDef( Class parameterType, int order) { final SqlParameterDefinition definition; - ManyToOne manyToOne = getAnnotation(objectType, parameterName, ManyToOne.class); - if (manyToOne != null) { - Class subK = manyToOne.targetEntity(); - if (subK == null || subK.equals(void.class)) { - subK = parameterType; + + final Class manyToOneClass; // if manyToOneClass == null ==> this parameter is simple; it's complex otherwise. + final FetchType fetch; + { + final ManyToOne manyToOne = getAnnotation(objectType, parameterName, ManyToOne.class); + if (manyToOne != null) { + Class subK = manyToOne.targetEntity(); + // void.class is the default; the documentation forces usage of the the parameter type in the default case. + if (subK == null || subK.equals(void.class)) { + subK = parameterType; + } + + manyToOneClass = subK; + fetch = manyToOne.fetch(); + } else if (config.doAutoDetermineManyToOne() && isClassComplex(parameterType)) { + final SqlObjectDefinition pd = SqlObjectDefinition.fromClass(parameterType, config); + if (!pd.getIdParameters().isEmpty()) { + manyToOneClass = parameterType; + fetch = FetchType.EAGER; // todo probably the fetch type should be configurable. + } else { + manyToOneClass = null; + fetch = null; + } + } else { + manyToOneClass = null; + fetch = null; } + } + if (manyToOneClass != null) { JoinColumn joinColumn = getAnnotation(objectType, parameterName, JoinColumn.class); - SqlObjectDefinition od = SqlObjectDefinition.fromClass(subK, config); + SqlObjectDefinition od = SqlObjectDefinition.fromClass(manyToOneClass, config); checkState( ! od.getIdParameters().isEmpty(), "No id parameters"); String sn = null; if (joinColumn != null) sn = joinColumn.name(); if (sn == null) sn = config.getNamingStrategy().propertyToColumnName(parameterName); - FetchType fetch = manyToOne.fetch(); int depth; if (FetchType.LAZY == fetch) { depth = 1;