Skip to content
Permalink
Browse files

Allow @OnVersionChange methods that completely ignore schema versions.

  • Loading branch information...
archiecobbs committed Oct 29, 2019
1 parent 58cb387 commit 76e1d0fcc24c30a14fb447e7dba105ca47f1db1a
@@ -5,6 +5,7 @@ Version Next
- Added convenience method NavigableSetPager.reverseViewOrdering()
- Added method MutableView.setReadTrackingPaused()
- Map ValidationException to Spring DataIntegrityViolationException
- Allow @OnVersionChange methods that completely ignore schema versions
- Fixed a few minor Java expression parsing bugs

Version 4.1.5 Released May 21, 2019
@@ -45,7 +45,7 @@ protected boolean includeMethod(Method method, OnVersionChange annotation) {
this.checkReturnType(method, void.class);
final int numParams = method.getParameterTypes().length;

// Handle @OnVersionChange version numbers; allow both to be omitted
// Handle @OnVersionChange version numbers; as special case, allow both to be completely omitted
int index = 0;
if (!(annotation.oldVersion() == 0 && annotation.newVersion() == 0 && numParams == 1)) {
if (annotation.oldVersion() == 0)
@@ -122,24 +122,19 @@ void invoke(JObject jobj, int oldVersion, int newVersion,
return;

// Determine which map to provide
Map<?, Object> oldValues = this.byName ? oldValuesByName : oldValuesByStorageId;
final Map<?, Object> oldValues = this.byName ? oldValuesByName : oldValuesByStorageId;

// Invoke method
switch ((annotation.oldVersion() != 0 ? 2 : 0) + (annotation.newVersion() != 0 ? 1 : 0)) {
case 0:
Util.invoke(method, jobj, oldVersion, newVersion, oldValues);
break;
case 1:
Util.invoke(method, jobj, oldVersion, oldValues);
break;
case 2:
// Figure out method parameters and invoke method
if (annotation.oldVersion() != 0 && annotation.newVersion() != 0)
Util.invoke(method, jobj, oldValues);
else if (annotation.oldVersion() != 0)
Util.invoke(method, jobj, newVersion, oldValues);
break;
case 3:
default:
else if (annotation.newVersion() != 0)
Util.invoke(method, jobj, oldVersion, oldValues);
else if (method.getParameterTypes().length == 1) // special case where version numbers are completely ignored
Util.invoke(method, jobj, oldValues);
break;
}
else
Util.invoke(method, jobj, oldVersion, newVersion, oldValues);
}

@Override
@@ -23,15 +23,37 @@
*
* <p>
* The annotated method must be an instance method (i.e., not static), return void, and
* take one, two, or all three of the following parameters in order:
* take zero, one, two, or all three of the following parameters (in this order):
* <ol>
* <li>{@code int oldVersion} - previous schema version; should be present only if {@link #oldVersion} is zero</li>
* <li>{@code int newVersion} - new schema version; should be present only if {@link #newVersion} is zero</li>
* <li>{@code int oldVersion} - previous schema version; required if {@link #oldVersion} is unspecified (i.e., zero)</li>
* <li>{@code int newVersion} - new schema version; required if {@link #newVersion} is unspecified (i.e., zero)</li>
* <li>{@code Map<Integer, Object> oldValues} <i>or</i> {@code Map<String, Object> oldValues} - immutable map containing
* all field values from the previous version of the object, indexed by either storage ID or field name.</li>
* </ol>
*
* <p>
* In addition to the above options, you may also completely ignore the schema version numberss by leaving {@link #oldVersion}
* and {@link #newVersion} unspecified and declaring the method with only the {@code oldValues} parameter.
* In many cases, this is the simplest way to handle schema changes: ignore version numbers and instead just using the
* presence or absence of fields in {@code oldValues} to determine what migration work needs to be done. For example:
* <pre>
* &#64;OnVersionChange
* private void applySchemaChanges(Map&lt;String, Object&gt; oldValues) {
* if (!oldValues.containsKey("balance")) // at some point we added a new field "balance"
* this.setBalance(DEFAULT_BALANCE);
* if (oldValues.containsKey("fullName")) { // we replaced "fullName" with "lastName" &amp; "firstName"
* final String fullName = (String)oldValues.get("fullName");
* if (fullName != null) {
* final int comma = fullName.indexOf(',');
* this.setLastName(comma == -1 ? null : fullName.substring(0, comma));
* this.setFirstName(fullName.substring(comma + 1).trim());
* }
* }
* // ...etc
* }
* </pre>
*
* <p>
* If a class has multiple {@link OnVersionChange &#64;OnVersionChange}-annotated methods, methods with more specific
* constraint(s) (i.e., non-zero {@link #oldVersion} and/or {@link #newVersion}) will be invoked first.
*
@@ -448,6 +448,11 @@ private void versionChange(int oldVersion, Map<Integer, Object> oldValues) {
break;
}
}

// Version numbers being completely ignored
@OnVersionChange
private void versionChange2(Map<Integer, Object> oldValues) {
}
}

@PermazenType(storageId = 200, autogenFields = false)

0 comments on commit 76e1d0f

Please sign in to comment.
You can’t perform that action at this time.