diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java
index 60d759892..608d9c221 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java
@@ -330,9 +330,15 @@ public class ClassMappingInfo
_uniques.add(unique);
}
+ public Unique[] getUniques() {
+ return (_uniques == null) ? new Unique[0] :
+ (Unique[])_uniques.toArray(new Unique[_uniques.size()]);
+ }
+
public Unique[] getUniques(ClassMapping cm, boolean adapt) {
if (_uniques == null || _uniques.isEmpty())
return new Unique[0];
+
Iterator uniqueConstraints = _uniques.iterator();
Table table = cm.getTable();
Collection result = new ArrayList();
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java
index 0a527829a..c62579958 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java
@@ -32,6 +32,7 @@ enum MappingTag {
ATTR_OVERRIDE,
ATTR_OVERRIDES,
COL,
+ COLUMN_NAME,
COLUMN_RESULT,
DISCRIM_COL,
DISCRIM_VAL,
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
index 04d7dd738..3fb45a90c 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
@@ -69,6 +69,7 @@ public class XMLPersistenceMappingParser
_elems.put("association-override", ASSOC_OVERRIDE);
_elems.put("attribute-override", ATTR_OVERRIDE);
_elems.put("column", COL);
+ _elems.put("column-name", COLUMN_NAME);
_elems.put("column-result", COLUMN_RESULT);
_elems.put("discriminator-column", DISCRIM_COL);
_elems.put("discriminator-value", DISCRIM_VAL);
@@ -85,6 +86,7 @@ public class XMLPersistenceMappingParser
_elems.put("table", TABLE);
_elems.put("table-generator", TABLE_GEN);
_elems.put("temporal", TEMPORAL);
+ _elems.put("unique-constraint", UNIQUE);
}
private static final Localizer _loc = Localizer.forPackage
@@ -220,8 +222,7 @@ public class XMLPersistenceMappingParser
ret = startTableGenerator(attrs);
break;
case UNIQUE:
- getLog().warn(_loc.get("unique-constraints", currentElement()));
- ret = false;
+ ret = startUniqueConstraint(attrs);
break;
case TEMPORAL:
case ENUMERATED:
@@ -239,6 +240,9 @@ public class XMLPersistenceMappingParser
case COLUMN_RESULT:
ret = startColumnResult(attrs);
break;
+ case COLUMN_NAME:
+ ret = true;
+ break;
default:
ret = false;
}
@@ -277,6 +281,12 @@ public class XMLPersistenceMappingParser
case ENTITY_RESULT:
endEntityResult();
break;
+ case UNIQUE:
+ endUniqueConstraint();
+ break;
+ case COLUMN_NAME:
+ endColumnName();
+ break;
}
}
@@ -846,6 +856,52 @@ public class XMLPersistenceMappingParser
return true;
}
+ /**
+ * Starts processing <unique-constraint> provided the tag occurs
+ * within a ClassMapping element and not within a secondary
+ * table.
+ * Pushes the Unique element in the stack.
+ */
+ private boolean startUniqueConstraint(Attributes attrs)
+ throws SAXException {
+ Object current = currentElement();
+ if (current instanceof ClassMapping && _secondaryTable == null) {
+ Unique unique = new Unique();
+ pushElement(unique);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Ends processing <unique-constraint> provided the tag occurs
+ * within a ClassMapping element and not within a secondary
+ * table. The stack is popped and the Unique element is added to the
+ * ClassMappingInfo.
+ */
+ private void endUniqueConstraint() {
+ Unique unique = (Unique)popElement();
+ Object current = currentElement();
+ if (current instanceof ClassMapping && _secondaryTable == null)
+ ((ClassMapping)current).getMappingInfo().addUnique(unique);
+ }
+
+ /**
+ * Ends processing <column-name> tag by adding the column name in
+ * the current Unique element that resides in the top of the stack.
+ */
+ private boolean endColumnName() {
+ Object current = currentElement();
+ if (current instanceof Unique) {
+ Unique unique = (Unique)current;
+ Column column = new Column();
+ column.setName(this.currentText());
+ unique.addColumn(column);
+ return true;
+ }
+ return false;
+ }
+
/**
* Track unique column settings.
*/
diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java
index 755020432..500b76a53 100644
--- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java
+++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java
@@ -42,6 +42,7 @@ import org.apache.openjpa.jdbc.meta.strats.FlatClassStrategy;
import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
@@ -181,9 +182,10 @@ public class XMLPersistenceMappingSerializer
ClassMapping cls = (ClassMapping) mapping;
ClassMappingInfo info = cls.getMappingInfo();
serializeTable(info.getTableName(), "table", Strings
- .getClassName(mapping.getDescribedType()), null);
+ .getClassName(mapping.getDescribedType()), null,
+ info.getUniques());
for (String second : info.getSecondaryTableNames())
- serializeTable(second, "secondary-table", null, info);
+ serializeTable(second, "secondary-table", null, info, null);
serializeColumns(info, ColType.PK_JOIN, null);
}
@@ -218,14 +220,15 @@ public class XMLPersistenceMappingSerializer
* in the given {@link ClassMappingInfo}.
*/
private void serializeTable(String table, String elementName,
- String defaultName, ClassMappingInfo secondaryInfo)
+ String defaultName, ClassMappingInfo secondaryInfo, Unique[] uniques)
throws SAXException {
List cols = null;
if (secondaryInfo != null)
cols = (List) secondaryInfo.getSecondaryTableJoinColumns
(table);
- boolean print = cols != null && cols.size() > 0;
+ boolean print = (cols != null && cols.size() > 0) ||
+ (uniques !=null || uniques.length > 0);
if (table != null
&& (defaultName == null || !defaultName.equals(table))) {
print = true;
@@ -243,6 +246,9 @@ public class XMLPersistenceMappingSerializer
for (Column col : cols)
serializeColumn(col, ColType.PK_JOIN, null, false);
}
+ if (uniques != null)
+ for (Unique unique: uniques)
+ serializeUniqueConstraint(unique);
endElement(elementName);
}
}
@@ -509,6 +515,17 @@ public class XMLPersistenceMappingSerializer
}
}
+ private void serializeUniqueConstraint(Unique unique) throws SAXException {
+ startElement("unique-constraint");
+ Column[] columns = unique.getColumns();
+ for (Column column:columns) {
+ startElement("column-name");
+ addText(column.getName());
+ endElement("column-name");
+ }
+ endElement("unique-constraint");
+ }
+
@Override
protected SerializationComparator newSerializationComparator() {
return new MappingSerializationComparator();