From 222b3c1eaaad00ce9face0868ec69ce96a27cbdb Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 1 Aug 2007 03:22:51 +0000 Subject: JDBCRepository allows non-null column to be @Nullable if also @Independent. Fixed bug in generating SQL with nullable primary key properties. --- .../carbonado/repo/jdbc/JDBCStorableGenerator.java | 61 ++++++++++++++++------ .../repo/jdbc/JDBCStorableIntrospector.java | 13 +++-- 2 files changed, 55 insertions(+), 19 deletions(-) (limited to 'src/main/java/com/amazon/carbonado') diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java index 0e5b74e..f86ab27 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java @@ -79,8 +79,9 @@ class JDBCStorableGenerator { // Modes for automatic versioning when setting PreparedStatement values. private static final int NORMAL = 0; - private static final int INITIAL_VERSION = 1; - private static final int INCREMENT_VERSION = 2; + private static final int NOT_NULL = 1; + private static final int INITIAL_VERSION = 2; + private static final int INCREMENT_VERSION = 3; private static final Map> cCache; @@ -837,9 +838,9 @@ class JDBCStorableGenerator { } b.loadConstant(property.getColumnName()); CodeBuilderUtil.callStringBuilderAppendString(b); - if (property.isNullable()) { - // TODO: Support null primary key or version property. Is this possible? - throw new UnsupportedOperationException(); + if (false && property.isNullable()) { + // FIXME: Support null primary key or version property. + throw new UnsupportedOperationException(property.toString()); } else { b.loadConstant("=?"); CodeBuilderUtil.callStringBuilderAppendString(b); @@ -931,9 +932,9 @@ class JDBCStorableGenerator { // statement. for (JDBCStorableProperty property : whereProperties) { - if (property.isNullable()) { - // TODO: Support null primary key or version property. Is this possible? - throw new UnsupportedOperationException(); + if (false && property.isNullable()) { + // FIXME: Support null primary key or version property. + throw new UnsupportedOperationException(property.toString()); } else { b.loadLocal(psVar); b.loadLocal(indexVar); @@ -1349,32 +1350,60 @@ class JDBCStorableGenerator { Label tryAfterPs = b.createLabel().setLocation(); // Now set where clause parameters. + Label nextProperty = null; + LocalVariable paramIndexVar = null; ordinal = 0; for (JDBCStorableProperty property : properties) { if (!property.isSelectable()) { continue; } - Label nextProperty = b.createLabel(); + if (paramIndexVar == null) { + ordinal++; + } else { + b.integerIncrement(paramIndexVar, 1); + } + + if (nextProperty != null) { + nextProperty.setLocation(); + nextProperty = null; + } + + nextProperty = b.createLabel(); final TypeDesc propertyType = TypeDesc.forClass(property.getType()); - if (!property.isNullable()) { - b.loadLocal(psVar); - b.loadConstant(++ordinal); - } else { + if (property.isNullable()) { // Nullable properties are dynamically added to where clause, // and are at the end of the prepared statement. If value is // null, then skip to the next property, since the statement // was appended earlier with "IS NULL". + + // Cannot use constant parameter index anymore. + if (paramIndexVar == null) { + paramIndexVar = b.createLocalVariable(null, TypeDesc.INT); + b.loadConstant(ordinal); + b.storeLocal(paramIndexVar); + } + b.loadThis(); b.loadField(superType, property.getName(), propertyType); b.ifNullBranch(nextProperty, true); } - setPreparedStatementValue(b, property, NORMAL, null, instanceVar, null, null); + b.loadLocal(psVar); + if (paramIndexVar == null) { + b.loadConstant(ordinal); + } else { + b.loadLocal(paramIndexVar); + } + + setPreparedStatementValue(b, property, NOT_NULL, null, instanceVar, null, null); + } + if (nextProperty != null) { nextProperty.setLocation(); + nextProperty = null; } return tryAfterPs; @@ -1392,7 +1421,7 @@ class JDBCStorableGenerator { * the original lob. An update statement needs to be issued after the load * to insert/update the large value. * - * @param mode one of NORMAL, INITIAL_VERSION or INCREMENT_VERSION + * @param mode one of NORMAL, NOT_NULL, INITIAL_VERSION or INCREMENT_VERSION * @param instanceVar when null, assume properties are contained in * "this". Otherwise, invoke property access methods on storable referenced * in var. @@ -1464,7 +1493,7 @@ class JDBCStorableGenerator { CodeBuilderUtil.initialVersion(b, fromType, 1); } else if (mode == INCREMENT_VERSION) { CodeBuilderUtil.incrementVersion(b, fromType); - } else if (!fromType.isPrimitive()) { + } else if (!fromType.isPrimitive() && mode != NOT_NULL) { // Handle case where property value is null. b.dup(); Label notNull = b.createLabel(); diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java index 4805ee2..bc0c29a 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java @@ -325,7 +325,7 @@ public class JDBCStorableIntrospector extends StorableIntrospector { "\" must have a Nullable annotation"); } } else { - if (mainProperty.isNullable()) { + if (mainProperty.isNullable() && !mainProperty.isIndependent()) { errorMessages.add ("Property \"" + mainProperty.getName() + "\" must not have a Nullable annotation"); @@ -498,11 +498,18 @@ public class JDBCStorableIntrospector extends StorableIntrospector { do { String columnName = rs.getString("COLUMN_NAME"); String propertyName = columnToProperty.remove(columnName); + + if (propertyName == null) { + errorMessages.add + ("Column \"" + columnName + "\" must be part of primary key"); + continue; + } + StorableProperty mainProperty = mainProperties.get(propertyName); if (!mainProperty.isPrimaryKeyMember()) { errorMessages.add - ("Property \"" + propertyName + "\" must be a primary key member"); + ("Property \"" + propertyName + "\" must be part of primary key"); } } while (rs.next()); } finally { @@ -515,7 +522,7 @@ public class JDBCStorableIntrospector extends StorableIntrospector { if (mainProperty.isPrimaryKeyMember()) { errorMessages.add - ("Property \"" + propertyName + "\" cannot be a primary key member"); + ("Property \"" + propertyName + "\" cannot be part of primary key"); } } } -- cgit v1.2.3