Skip to content

Commit 4237550

Browse files
authored
Constructor parameter changes (#26)
- Allowed the name of the constructor argument to be derived from the java name. This requires passing the '-parameters' flag to javac, otherwise the argument names get stripped out and become arg0, arg1, etc. - Updated the documentation to reflect this change.
1 parent 86741fb commit 4237550

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,10 @@ public class ConstructedClass {
294294
}
295295
```
296296
297-
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the record on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor, but we need to provide this missing information with annotations:
297+
As it stands, this class cannot be used with the AeroMapper because there is no valid constructor to invoke when an object needs to be created. There is a constructor but it does not contain enough information to map the record on the database to the parameters of the constructor. (Remember that at runtime method and argument names are typically lost and become "arg1", "arg2" and so on). We can use this constructor in one of two ways:
298+
299+
1. We specify '-parameters' to javac, which will prevent it stripping out the names to the constructor
300+
2. We can to provide this missing information with annotations:
298301
299302
```java
300303
@AerospikeRecord(namespace = "test", set = "testSet")
@@ -318,7 +321,7 @@ public class ConstructedClass {
318321
}
319322
```
320323
321-
Now there is enough information to be able to construct an instance of this class from a database record. Note that the names of the @ParamFrom annotation are the bin names, not the underlying field names. So if you have a field declared as
324+
Now there is enough information to be able to construct an instance of this class from a database record. Note that the names of the @ParamFrom annotation (or the argument names if using -parameters) are the bin names, not the underlying field names. So if you have a field declared as
322325
323326
```java
324327
@AerospikeBin(name = "shrtNm")

src/main/java/com/aerospike/mapper/tools/ClassCacheEntry.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,20 +348,28 @@ private void findConstructor() {
348348
current = current.superClazz;
349349
}
350350
int count = 0;
351+
352+
// Parameters can be either specified by their name (which requires the use of the javac -parameters flag), or through an @ParamFrom annotation.
351353
for (Parameter thisParam : params) {
352354
count++;
355+
boolean isFromAnnotation = false;
356+
String binName = thisParam.getName();
353357
ParamFrom parameterDetails = thisParam.getAnnotation(ParamFrom.class);
354-
if (parameterDetails == null) {
355-
throw new AerospikeException("Class " + clazz.getSimpleName() + " has a preferred constructor of " + desiredConstructor.toString()+ ". However, parameter " + count +
356-
" is not marked with a @ParamFrom annotation, and hence cannot be determined how to map to this from the bins in the record.");
358+
359+
if (parameterDetails != null) {
360+
binName = parameterDetails.value();
361+
isFromAnnotation = true;
357362
}
358-
String binName = parameterDetails.value();
359363

360364
// Validate that we have such a value
361365
if (!allValues.containsKey(binName)) {
362366
String valueList = String.join(",", values.keySet());
363-
throw new AerospikeException("Class " + clazz.getSimpleName() + " has a preferred constructor of " + desiredConstructor.toString()+ ". However, parameter " + count +
364-
" is mapped to bin \"" + binName + "\" which is not one of the values on the class, which are: " + valueList);
367+
String message = String.format("Class %s has a preferred constructor of %s. However, parameter %d is mapped to bin \"%s\" %s which is not one of the values on the class, which are: %s%s",
368+
clazz.getSimpleName(), desiredConstructor.toString(), count, binName,
369+
isFromAnnotation ? "via the @ParamFrom annotation" : "via the argument name",
370+
valueList,
371+
(!isFromAnnotation && binName.startsWith("arg")) ? ". Did you forget to specify '-parameters' to javac when building?" : "");
372+
throw new AerospikeException(message);
365373
}
366374
Class<?> type = thisParam.getType();
367375
if (!type.isAssignableFrom(allValues.get(binName).getType())) {

0 commit comments

Comments
 (0)