You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/06/27 00:04:07 UTC
svn commit: r672038 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/
openjpa-jdbc/src/main/resources/org/...
Author: ppoddar
Date: Thu Jun 26 15:04:06 2008
New Revision: 672038
URL: http://svn.apache.org/viewvc?rev=672038&view=rev
Log:
OPENJPA-340: Support for @UniqueConstraints on @TableGenerator, @SecondaryTable and @JoinTable.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUnique.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/SequenceMapping.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java
openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingSerializer.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java
openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/org/apache/openjpa/persistence/jdbc/localizer.properties
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java Thu Jun 26 15:04:06 2008
@@ -28,6 +28,7 @@
import javax.transaction.NotSupportedException;
+import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@@ -38,6 +39,7 @@
import org.apache.openjpa.jdbc.schema.SchemaTool;
import org.apache.openjpa.jdbc.schema.Schemas;
import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.RowImpl;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
@@ -49,6 +51,8 @@
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.InvalidStateException;
+import org.apache.openjpa.util.UserException;
+
import serp.util.Numbers;
import serp.util.Strings;
@@ -86,6 +90,7 @@
private String _table = "OPENJPA_SEQUENCE_TABLE";
private String _seqColumnName = "SEQUENCE_VALUE";
private String _pkColumnName = "ID";
+ private String[] _uniqueColumnNames;
private Column _seqColumn = null;
private Column _pkColumn = null;
@@ -191,6 +196,20 @@
public void setInitialValue(int intValue) {
_intValue = intValue;
}
+
+ /**
+ * Sets the names of the columns on which a unique constraint is set.
+ * @param columnsNames are passed as a single String concatenated with
+ * a '|' character. This method parses it back to array of Strings.
+ */
+ public void setUniqueColumns(String columnNames) {
+ _uniqueColumnNames = (StringUtils.isEmpty(columnNames))
+ ? null : StringUtils.split(columnNames, '|');
+ }
+
+ public String getUniqueColumns() {
+ return StringUtils.join(_uniqueColumnNames, '|');
+ }
/**
* @deprecated Use {@link #setAllocate}. Retained for backwards
@@ -235,7 +254,12 @@
if (schema == null)
schema = group.addSchema(schemaName);
- schema.importTable(_pkColumn.getTable());
+ Table copy = schema.importTable(_pkColumn.getTable());
+ // importTable() does not import unique constraints
+ Unique[] uniques = _pkColumn.getTable().getUniques();
+ for (Unique u : uniques) {
+ copy.importUnique(u);
+ }
// we need to reset the table name in the column with the
// fully qualified name for matching the table name from the
// Column.
@@ -244,7 +268,6 @@
// some databases require to create an index for the sequence table
_conf.getDBDictionaryInstance().createIndexIfNecessary(schema,
_table, _pkColumn);
-
}
}
@@ -361,6 +384,19 @@
(_seqColumnName, table));
_seqColumn.setType(dict.getPreferredType(Types.BIGINT));
_seqColumn.setJavaType(JavaTypes.LONG);
+
+ if (_uniqueColumnNames != null) {
+ String uniqueName = dict.getValidUniqueName("UNQ", table);
+ Unique u = table.addUnique(uniqueName);
+ for (String columnName : _uniqueColumnNames) {
+ if (!table.containsColumn(columnName))
+ throw new UserException(_loc.get("unique-missing-column",
+ columnName, table.getName(), table.getColumnNames()));
+ Column col = table.getColumn(columnName);
+ u.addColumn(col);
+ }
+ }
+
}
/**
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ClassMappingInfo.java Thu Jun 26 15:04:06 2008
@@ -19,13 +19,13 @@
package org.apache.openjpa.jdbc.meta;
import java.io.File;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Collection;
-import java.util.ArrayList;
+import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
@@ -38,6 +38,7 @@
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.xml.Commentable;
+import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.util.UserException;
/**
@@ -64,7 +65,8 @@
private File _file = null;
private int _srcType = SRC_OTHER;
private String[] _comments = null;
- private Collection _uniques = null;//Unique
+ // Unique constraints indexed by primary or secondary table name
+ private Map<String,List<Unique>> _uniques;
/**
* The described class name.
@@ -221,11 +223,12 @@
_seconds = new HashMap();
_seconds.put(tableName, cols);
}
-
+
/**
- * Return the table for the given class.
+ * Return the named table for the given class.
*/
- public Table getTable(final ClassMapping cls, boolean adapt) {
+ public Table getTable(final ClassMapping cls, String tableName,
+ boolean adapt) {
Table t = createTable(cls, new TableDefaults() {
public String get(Schema schema) {
// delay this so that we don't do schema reflection for unique
@@ -233,13 +236,20 @@
return cls.getMappingRepository().getMappingDefaults().
getTableName(cls, schema);
}
- }, _schemaName, _tableName, adapt);
+ }, _schemaName, tableName, adapt);
t.setComment(cls.getTypeAlias() == null
? cls.getDescribedType().getName()
: cls.getTypeAlias());
return t;
}
-
+
+ /**
+ * Return the primary table for the given class.
+ */
+ public Table getTable(final ClassMapping cls, boolean adapt) {
+ return getTable(cls, _tableName, adapt);
+ }
+
/**
* Return the datastore identity columns for the given class, based on the
* given templates.
@@ -340,51 +350,87 @@
_seconds.put(key, cinfo._seconds.get(key));
}
}
- if (cinfo._uniques != null)
- _uniques = new ArrayList(cinfo._uniques);
- }
+ if (cinfo._uniques != null) {
+ if (_uniques == null)
+ _uniques = new HashMap<String, List<Unique>>();
+ for (Entry<String, List<Unique>> entry : cinfo._uniques.entrySet())
+ if (!_uniques.containsKey(entry.getKey()))
+ _uniques.put(entry.getKey(), entry.getValue());
+ }
- public void addUnique(Unique unique) {
- if (unique == null)
- return;
+ }
+
+ /**
+ * Add a unique constraint for the given table.
+ * @param table must be primary table or secondary table name added a
+ * priori to this receiver.
+ * @param unique the unique constraint. null means no-op.
+ */
+ public void addUnique(String table, Unique unique) {
+ if (!StringUtils.equals(_tableName, table) &&
+ (_seconds == null || !_seconds.containsKey(table))) {
+ throw new UserException(_loc.get("unique-no-table",
+ new Object[]{table, _className, _tableName,
+ ((_seconds == null) ? "" : _seconds.keySet())}));
+ }
+ if (unique == null)
+ return;
if (_uniques == null)
- _uniques = new ArrayList();
- _uniques.add(unique);
+ _uniques = new HashMap<String,List<Unique>>();
+ unique.setTableName(table);
+ List<Unique> uniques = _uniques.get(table);
+ if (uniques == null) {
+ uniques = new ArrayList<Unique>();
+ uniques.add(unique);
+ _uniques.put(table, uniques);
+ } else {
+ uniques.add(unique);
+ }
}
- public Unique[] getUniques() {
- return (_uniques == null) ? new Unique[0] :
- (Unique[])_uniques.toArray(new Unique[_uniques.size()]);
+ /**
+ * Get the unique constraints of the given primary or secondary table.
+ */
+ public Unique[] getUniques(String table) {
+ if (_uniques == null || _uniques.isEmpty()
+ || _uniques.containsKey(table))
+ return new Unique[0];
+ List<Unique> uniques = _uniques.get(table);
+ return uniques.toArray(new Unique[uniques.size()]);
}
- public Unique[] getUniques(ClassMapping cm, boolean adapt) {
+ /**
+ * Get all the unique constraints associated with both the primary and/or
+ * secondary tables.
+ *
+ */
+ public Unique[] getUniques(MetaDataContext cm, boolean adapt) {
if (_uniques == null || _uniques.isEmpty())
return new Unique[0];
-
- Iterator uniqueConstraints = _uniques.iterator();
- Table table = cm.getTable();
- Collection result = new ArrayList();
- while (uniqueConstraints.hasNext()) {
- Unique template = (Unique) uniqueConstraints.next();
- Column[] templateColumns = template.getColumns();
- Column[] uniqueColumns = new Column[templateColumns.length];
- boolean missingColumn = true;
- for (int i=0; i<uniqueColumns.length; i++) {
- String columnName = templateColumns[i].getName();
- Column uniqueColumn = table.getColumn(columnName);
- missingColumn = (uniqueColumn == null);
- if (missingColumn) {
- throw new UserException(_loc.get("missing-unique-column",
- cm, table, columnName));
- }
- uniqueColumns[i] = uniqueColumn;
- }
- Unique unique = super.createUnique(cm, "unique", template,
- uniqueColumns, adapt);
- if (unique != null)
- result.add(unique);
+ List<Unique> result = new ArrayList<Unique>();
+ for (String tableName : _uniques.keySet()) {
+ List<Unique> uniqueConstraints = _uniques.get(tableName);
+ for (Unique template : uniqueConstraints) {
+ Column[] templateColumns = template.getColumns();
+ Column[] uniqueColumns = new Column[templateColumns.length];
+ Table table = getTable((ClassMapping)cm, tableName, adapt);
+ for (int i=0; i<uniqueColumns.length; i++) {
+ String columnName = templateColumns[i].getName();
+ if (!table.containsColumn(columnName)) {
+ throw new UserException(_loc.get("unique-missing-column",
+ new Object[]{cm, columnName, tableName,
+ table.getColumnNames()}));
+ }
+ Column uniqueColumn = table.getColumn(columnName);
+ uniqueColumns[i] = uniqueColumn;
+ }
+ Unique unique = createUnique(cm, "unique", template,
+ uniqueColumns, adapt);
+ if (unique != null)
+ result.add(unique);
+ }
}
- return (Unique[]) result.toArray(new Unique[result.size()]);
+ return result.toArray(new Unique[result.size()]);
}
public File getSourceFile() {
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Thu Jun 26 15:04:06 2008
@@ -70,7 +70,8 @@
private Index _idx = null;
private boolean _outer = false;
private int _fetchMode = Integer.MAX_VALUE;
-
+ private Unique[] _joinTableUniques; // Unique constraints on JoinTable
+
/**
* Constructor.
*/
@@ -183,6 +184,14 @@
_unq = unq;
}
+ public Unique[] getJoinTableUniques() {
+ return _joinTableUniques;
+ }
+
+ public void setJoinTableUniques(Unique[] unqs) {
+ _joinTableUniques = unqs;
+ }
+
/**
* Index on join foreign key columns.
*/
@@ -252,6 +261,13 @@
_val.refSchemaComponents();
_key.refSchemaComponents();
_elem.refSchemaComponents();
+ if (_joinTableUniques != null) {
+ for (Unique joinUnique : _joinTableUniques) {
+ for (Column col : joinUnique.getColumns()) {
+ col.ref();
+ }
+ }
+ }
}
/**
@@ -538,6 +554,7 @@
_io = _info.getColumnIO();
_outer = _info.isJoinOuter();
_unq = _info.getJoinUnique(this, false, adapt);
+ _joinTableUniques = _info.getJoinTableUniques(this, false, adapt);
_idx = _info.getJoinIndex(this, adapt);
}
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java Thu Jun 26 15:04:06 2008
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.meta;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.apache.openjpa.jdbc.schema.Column;
@@ -31,7 +33,9 @@
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.xml.Commentable;
import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.util.MetaDataException;
+import org.apache.openjpa.util.UserException;
/**
* Information about the mapping from a field to the schema, in raw form.
@@ -40,6 +44,7 @@
* with the relevant pieces of information filled in.
*
* @author Abe White
+ * @author Pinaki Poddar
*/
public class FieldMappingInfo
extends MappingInfo
@@ -53,6 +58,7 @@
private Column _orderCol = null;
private boolean _canOrderCol = true;
private String[] _comments = null;
+ private List<Unique> _joinTableUniques; // Unique constraints on the JoinTable
/**
* The user-supplied name of the table for this field.
@@ -185,8 +191,47 @@
getJoinUnique(field, fk.getTable(), fk.getColumns());
return createUnique(field, "join", unq, fk.getColumns(), adapt);
}
-
+
/**
+ * Add Unique Constraint to the Join Table.
+ */
+ public void addJoinTableUnique(Unique u) {
+ if (_joinTableUniques == null)
+ _joinTableUniques = new ArrayList<Unique>();
+ _joinTableUniques.add(u);
+ }
+
+ /**
+ * Get the unique constraints associated with the Sequence table.
+ */
+ public Unique[] getJoinTableUniques(FieldMapping field, boolean def,
+ boolean adapt) {
+ return getUniques(field, _joinTableUniques, def, adapt);
+ }
+
+ private Unique[] getUniques(FieldMapping field, List<Unique> uniques,
+ boolean def, boolean adapt) {
+ if (uniques == null || uniques.isEmpty())
+ return new Unique[0];
+ Collection<Unique> result = new ArrayList<Unique>();
+ for (Unique template : uniques) {
+ Column[] templateColumns = template.getColumns();
+ Column[] uniqueColumns = new Column[templateColumns.length];
+ Table table = getTable(field, true, adapt);
+ for (int i=0; i<uniqueColumns.length; i++) {
+ String columnName = templateColumns[i].getName();
+ Column uniqueColumn = table.getColumn(columnName);
+ uniqueColumns[i] = uniqueColumn;
+ }
+ Unique unique = createUnique(field, "unique", template,
+ uniqueColumns, adapt);
+ if (unique != null)
+ result.add(unique);
+ }
+ return result.toArray(new Unique[result.size()]);
+ }
+
+ /**
* Index on the field join.
*/
public Index getJoinIndex(FieldMapping field, boolean adapt) {
@@ -261,6 +306,7 @@
syncIndex(field, field.getJoinIndex());
syncUnique(field, field.getJoinUnique());
+ syncJoinTableUniques(field, field.getJoinTableUniques());
syncOrderColumn(field);
syncStrategy(field);
}
@@ -290,6 +336,24 @@
else
_orderCol = null;
}
+
+ /**
+ * Sets internal constraint information to match given mapped constraint.
+ */
+ protected void syncJoinTableUniques(MetaDataContext context, Unique[] unqs) {
+ if (unqs == null) {
+ _joinTableUniques = null;
+ return;
+ }
+ _joinTableUniques = new ArrayList<Unique>();
+ for (Unique unique:unqs) {
+ Unique copy = new Unique();
+ copy.setName(unique.getName());
+ copy.setDeferred(unique.isDeferred());
+ _joinTableUniques.add(unique);
+ }
+ }
+
public boolean hasSchemaComponents() {
return super.hasSchemaComponents() || _tableName != null
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java Thu Jun 26 15:04:06 2008
@@ -927,7 +927,7 @@
context, dict.platform));
deferred = false;
}
-
+
Unique unq = table.addUnique(name);
unq.setDeferred(deferred);
unq.setColumns(cols);
@@ -1534,7 +1534,7 @@
_unq.setName(unq.getName());
_unq.setDeferred(unq.isDeferred());
}
-
+
/**
* Sets internal constraint and column information to match given mapped
* constraint.
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/SequenceMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/SequenceMapping.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/SequenceMapping.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/SequenceMapping.java Thu Jun 26 15:04:06 2008
@@ -19,11 +19,16 @@
package org.apache.openjpa.jdbc.meta;
import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCSeqValue;
import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
import org.apache.openjpa.jdbc.kernel.TableJDBCSeq;
import org.apache.openjpa.jdbc.kernel.ValueTableJDBCSeq;
+import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.lib.conf.PluginValue;
import org.apache.openjpa.meta.SequenceMetaData;
@@ -55,13 +60,15 @@
private static final String PROP_SEQUENCE_COL = "SequenceColumn";
private static final String PROP_PK_COL = "PrimaryKeyColumn";
private static final String PROP_PK_VALUE = "PrimaryKeyValue";
+ private static final String PROP_UNIQUE = "UniqueColumns";
private File _mapFile = null;
private String _table = null;
private String _sequenceColumn = null;
private String _primaryKeyColumn = null;
private String _primaryKeyValue = null;
-
+ private String[] _uniqueColumns = null;
+
public SequenceMapping(String name, MappingRepository repos) {
super(name, repos);
}
@@ -138,6 +145,14 @@
_primaryKeyValue = primaryKeyValue;
}
+ public void setUniqueColumns(String[] cols) {
+ _uniqueColumns = cols;
+ }
+
+ public String[] getUniqueColumns() {
+ return _uniqueColumns;
+ }
+
protected PluginValue newPluginValue(String property) {
return new JDBCSeqValue(property);
}
@@ -148,5 +163,11 @@
appendProperty(props, PROP_SEQUENCE_COL, _sequenceColumn);
appendProperty(props, PROP_PK_COL, _primaryKeyColumn);
appendProperty(props, PROP_PK_VALUE, _primaryKeyValue);
+ // Array of unique column names are passed to configuration
+ // as a single string "x|y|z". The configurable (TableJDBCSeq) must
+ // parse it back.
+ if (_uniqueColumns != null && _uniqueColumns.length > 0)
+ appendProperty(props, PROP_UNIQUE,
+ StringUtils.join(_uniqueColumns,'|'));
}
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java Thu Jun 26 15:04:06 2008
@@ -252,6 +252,11 @@
return _rels;
}
+ public String[] getColumnNames() {
+ return _colMap == null ? new String[0] :
+ (String[])_colMap.keySet().toArray(new String[_colMap.size()]);
+ }
+
/**
* Return the column with the given name, or null if none.
*/
@@ -260,6 +265,17 @@
return null;
return (Column) _colMap.get(name.toUpperCase());
}
+
+ /**
+ * Affirms if this table contains the column of the given name without any
+ * side-effect.
+ * @see Table#getColumn(String) can have side-effect of creating a column
+ * for dynamic table implementation.
+ */
+ public boolean containsColumn(String name) {
+ return name != null && _colMap != null
+ && _colMap.containsKey(name.toUpperCase());
+ }
/**
* Add a column to the table.
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Unique.java Thu Jun 26 15:04:06 2008
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.schema;
+import org.apache.commons.lang.StringUtils;
+
/**
* Represents a unique constraint. It can also represent a partial constraint.
*
@@ -25,11 +27,12 @@
*/
public class Unique
extends LocalConstraint {
-
+ private boolean _isAutoSetName = false;
/**
* Default constructor.
*/
public Unique() {
+ _isAutoSetName = true;
}
/**
@@ -45,6 +48,26 @@
public boolean isLogical() {
return false;
}
+
+ public void addColumn(Column col) {
+ super.addColumn(col);
+ col.setNotNull(true);
+ if (_isAutoSetName && getTable() == null) {
+ String pre = StringUtils.isEmpty(getName()) ? "UNQ" : getName();
+ setName(pre + "_" + col.getName());
+ _isAutoSetName = true;
+ }
+ }
+
+ /**
+ * Set the name of the constraint. This method cannot be called if the
+ * constraint already belongs to a table.
+ */
+ public void setName(String name) {
+ super.setName(name);
+ _isAutoSetName = false;
+ }
+
/**
* Return true if the structure of this primary key matches that of
Modified: openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties Thu Jun 26 15:04:06 2008
@@ -410,6 +410,8 @@
attempts to traverse through a non-relation field.
num-cols-path: Result path "{2}" in result type "{1}" of mapping "{0}" \
attempts to map a field that does not have exactly 1 column.
-missing-unique-column: A unique constraint specified in mapping of class "{0}" \
- to table "{1}" includes a column "{2}". However, the column does not \
- exist in "{1}" table.
+unique-missing-column: The column "{1}" in a unique constraint in "{0}" on \
+ table "{2}" can not be found in the list of available columns "{3}".
+unique-no-table: A unique constraint on table "{0}" can not be added to \
+ mapping of class "{1}" because the table does neither match its primary \
+ table "{2}" nor any of its secondary table(s) "{3}".
\ No newline at end of file
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java Thu Jun 26 15:04:06 2008
@@ -61,6 +61,7 @@
import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.FieldMappingInfo;
import org.apache.openjpa.jdbc.meta.MappingInfo;
import org.apache.openjpa.jdbc.meta.MappingRepository;
import org.apache.openjpa.jdbc.meta.QueryResultMapping;
@@ -80,6 +81,7 @@
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser;
import static org.apache.openjpa.persistence.jdbc.MappingTag.*;
import org.apache.openjpa.util.InternalException;
@@ -244,10 +246,16 @@
meta.setAllocate(gen.allocationSize());
meta.setSource(getSourceFile(), (el instanceof Class) ? el : null,
meta.SRC_ANNOTATIONS);
-
- //### EJB3
- if (gen.uniqueConstraints().length > 0 && log.isWarnEnabled())
- log.warn(_loc.get("unique-constraints", name));
+
+ switch (gen.uniqueConstraints().length) {
+ case 0:
+ break; // nothing to do
+ case 1:
+ meta.setUniqueColumns(gen.uniqueConstraints()[0].columnNames());
+ break;
+ default:
+ log.warn(_loc.get("unique-many-on-seq-unsupported", el, name));
+ }
}
@Override
@@ -464,8 +472,7 @@
Log log = getLog();
String name;
- List<Column> joins;
- boolean warnUnique = false;
+ List<Column> joins = null;
for (SecondaryTable table : tables) {
name = table.name();
if (StringUtils.isEmpty(name))
@@ -476,14 +483,10 @@
joins = new ArrayList<Column>(table.pkJoinColumns().length);
for (PrimaryKeyJoinColumn join : table.pkJoinColumns())
joins.add(newColumn(join));
- info.setSecondaryTableJoinColumns(name, joins);
- }
- warnUnique |= table.uniqueConstraints().length > 0;
+ }
+ info.setSecondaryTableJoinColumns(name, joins);
+ addUniqueConstraints(name, cm, info, table.uniqueConstraints());
}
-
- //### EJB3
- if (warnUnique && log.isWarnEnabled())
- log.warn(_loc.get("unique-constraints", cm));
}
/**
@@ -494,10 +497,38 @@
if (tableName != null)
cm.getMappingInfo().setTableName(tableName);
- for (UniqueConstraint uniqueConstraint:table.uniqueConstraints()) {
- Unique unique = newUnique(cm, null, uniqueConstraint.columnNames());
- cm.getMappingInfo().addUnique(unique);
- }
+ addUniqueConstraints(tableName, cm, cm.getMappingInfo(),
+ table.uniqueConstraints());
+ }
+
+ Unique createUniqueConstraint(MetaDataContext ctx, UniqueConstraint anno) {
+ String[] columnNames = anno.columnNames();
+ if (columnNames == null || columnNames.length == 0)
+ throw new UserException(_loc.get("unique-no-column", ctx));
+ Unique uniqueConstraint = new Unique();
+ for (int i=0; i<columnNames.length; i++) {
+ if (StringUtils.isEmpty(columnNames[i]))
+ throw new UserException(_loc.get("unique-empty-column",
+ Arrays.toString(columnNames), ctx));
+ Column column = new Column();
+ column.setName(columnNames[i]);
+ uniqueConstraint.addColumn(column);
+ }
+ return uniqueConstraint;
+ }
+
+ void addUniqueConstraints(String table, MetaDataContext ctx,
+ MappingInfo info, UniqueConstraint...uniqueConstraints) {
+ for (UniqueConstraint anno : uniqueConstraints) {
+ Unique unique = createUniqueConstraint(ctx, anno);
+ unique.setTableName(table);
+ if (info instanceof ClassMappingInfo)
+ ((ClassMappingInfo)info).addUnique(table, unique);
+ else if (info instanceof FieldMappingInfo)
+ ((FieldMappingInfo)info).addJoinTableUnique(unique);
+ else
+ throw new InternalException();
+ }
}
/**
@@ -1261,8 +1292,7 @@
}
unique |= (pcols[i].unique()) ? TRUE : FALSE;
- secondary = trackSecondaryTable(fm, secondary,
- pcols[i].table(), i);
+ secondary = trackSecondaryTable(fm, secondary, pcols[i].table(), i);
}
setColumns(fm, fm.getValueInfo(), cols, unique);
@@ -1337,11 +1367,13 @@
* Parse @JoinTable.
*/
private void parseJoinTable(FieldMapping fm, JoinTable join) {
- fm.getMappingInfo().setTableName(toTableName(join.schema(),
- join.name()));
- parseJoinColumns(fm, fm.getMappingInfo(), false, join.joinColumns());
+ FieldMappingInfo info = fm.getMappingInfo();
+ info.setTableName(toTableName(join.schema(), join.name()));
+ parseJoinColumns(fm, info, false, join.joinColumns());
parseJoinColumns(fm, fm.getElementMapping().getValueInfo(), false,
join.inverseJoinColumns());
+ addUniqueConstraints(info.getTableName(), fm, info,
+ join.uniqueConstraints());
}
/**
@@ -1617,21 +1649,4 @@
col.setFlag (Column.FLAG_UNUPDATABLE, !join.updatable ());
return col;
}
-
- private static Unique newUnique(ClassMapping cm, String name,
- String[] columnNames) {
- if (columnNames == null || columnNames.length == 0)
- return null;
- Unique uniqueConstraint = new Unique();
- uniqueConstraint.setName(name);
- for (int i=0; i<columnNames.length; i++) {
- if (StringUtils.isEmpty(columnNames[i]))
- throw new UserException(_loc.get("empty-unique-column",
- Arrays.toString(columnNames), cm));
- Column column = new Column();
- column.setName(columnNames[i]);
- uniqueConstraint.addColumn(column);
- }
- return uniqueConstraint;
- }
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingSerializer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingSerializer.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingSerializer.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingSerializer.java Thu Jun 26 15:04:06 2008
@@ -221,12 +221,12 @@
AnnotationBuilder abTable = addAnnotation(Table.class, mapping);
serializeTable(info.getTableName(), Strings
.getClassName(mapping.getDescribedType()), null,
- info.getUniques(), abTable);
+ info.getUniques(info.getTableName()), abTable);
serializeColumns(info, ColType.PK_JOIN, null, abTable, cls);
for (String second : info.getSecondaryTableNames()) {
AnnotationBuilder abSecTable =
addAnnotation(SecondaryTable.class, mapping);
- serializeTable(second, null, info, null, abSecTable);
+ serializeTable(second, null, info, info.getUniques(second), abSecTable);
}
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java Thu Jun 26 15:04:06 2008
@@ -39,6 +39,7 @@
import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
import org.apache.openjpa.jdbc.meta.DiscriminatorMappingInfo;
import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.MappingInfo;
import org.apache.openjpa.jdbc.meta.MappingRepository;
import org.apache.openjpa.jdbc.meta.QueryResultMapping;
import org.apache.openjpa.jdbc.meta.SequenceMapping;
@@ -56,6 +57,8 @@
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.XMLPersistenceMetaDataParser;
+import org.apache.openjpa.util.InternalException;
+
import static org.apache.openjpa.persistence.jdbc.MappingTag.*;
/**
@@ -293,6 +296,9 @@
case COLUMN_NAME:
endColumnName();
break;
+ case TABLE_GEN:
+ endTableGenerator();
+ break;
}
}
@@ -405,8 +411,13 @@
Object scope = (cur instanceof ClassMetaData)
? ((ClassMetaData) cur).getDescribedType() : null;
seq.setSource(getSourceFile(), scope, seq.SRC_XML);
+ pushElement(seq);
return true;
}
+
+ private void endTableGenerator() {
+ popElement();
+ }
/**
* Parse inheritance.
@@ -880,13 +891,9 @@
*/
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;
+ Unique unique = new Unique();
+ pushElement(unique);
+ return true;
}
/**
@@ -897,9 +904,23 @@
*/
private void endUniqueConstraint() {
Unique unique = (Unique) popElement();
- Object current = currentElement();
- if (current instanceof ClassMapping && _secondaryTable == null)
- ((ClassMapping) current).getMappingInfo().addUnique(unique);
+ Object ctx = currentElement();
+ String tableName = "?";
+ ClassMappingInfo info = null;
+ if (ctx instanceof ClassMapping) {
+ info = ((ClassMapping) ctx).getMappingInfo();
+ tableName = (_secondaryTable != null) ? info.getTableName() : _secondaryTable;
+ info.addUnique(tableName, unique);
+ } else if (ctx instanceof FieldMapping) {// JoinTable
+ info = ((FieldMapping)ctx).getDeclaringMapping().getMappingInfo();
+ tableName = info.getTableName();
+ info.addUnique(tableName, unique);
+ } else if (ctx instanceof SequenceMapping) {
+ tableName = ((SequenceMapping)ctx).getTable();
+ unique.setTableName(tableName);
+ } else {
+ throw new InternalException();
+ }
}
/**
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingSerializer.java Thu Jun 26 15:04:06 2008
@@ -186,9 +186,9 @@
ClassMappingInfo info = cls.getMappingInfo();
serializeTable(info.getTableName(), "table", Strings
.getClassName(mapping.getDescribedType()), null,
- info.getUniques());
+ info.getUniques(info.getTableName()));
for (String second : info.getSecondaryTableNames())
- serializeTable(second, "secondary-table", null, info, null);
+ serializeTable(second, "secondary-table", null, info, info.getUniques(second));
serializeColumns(info, ColType.PK_JOIN, null);
}
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/org/apache/openjpa/persistence/jdbc/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/org/apache/openjpa/persistence/jdbc/localizer.properties?rev=672038&r1=672037&r2=672038&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/org/apache/openjpa/persistence/jdbc/localizer.properties (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/resources/org/apache/openjpa/persistence/jdbc/localizer.properties Thu Jun 26 15:04:06 2008
@@ -46,8 +46,13 @@
Version columns must always be in the primary table of the class.
not-embedded: Attempt to declare mapping overrides on non-embedded field "{0}".
no-gen-table: No generated table found at "{0}".
-empty-unique-column: A unique constraint "{0}" specified in mapping of class \
+unique-no-column: A unique constraint specified in mapping of "{0}" specified \
+ no column.
+unique-empty-column: A unique constraint "{0}" specified in mapping of class \
"{1}" includes an empty column.
+unique-many-on-seq-unsupported: More than one unique constraints is specified \
+ on sequence generator "{1}" in "{0}". But multiple unique constraint on \
+ sequence generator is currently not supported.
discriminator-on-abstract-class: A discriminator value has been specified for \
the abstract class "{0}". The discriminator will never be used and may be \
safely removed.
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUnique.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUnique.java?rev=672038&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUnique.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/TestUnique.java Thu Jun 26 15:04:06 2008
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+public class TestUnique extends SQLListenerTestCase {
+ @Override
+ public void setUp(Object... props) {
+ super.setUp(UniqueA.class, UniqueB.class);
+ }
+
+ public void testMapping() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.getTransaction().commit();
+ em.close();
+ // The above should trigger schema definition
+
+ List<String> sqls = super.sql;
+
+ assertSQLFragnment(sqls, "CREATE TABLE UNIQUE_A",
+ "UNIQUE (a1, a2)",
+ "UNIQUE (a3, a4)");
+ assertSQLFragnment(sqls, "CREATE TABLE UNIQUE_B",
+ "UNIQUE (b1, b2)");
+ assertSQLFragnment(sqls, "CREATE TABLE UNIQUE_SECONDARY",
+ "UNIQUE (sa1)");
+ assertSQLFragnment(sqls, "CREATE TABLE UNIQUE_GENERATOR",
+ "UNIQUE (GEN1, GEN2)");
+ assertSQLFragnment(sqls, "CREATE TABLE UNIQUE_JOINTABLE",
+ "UNIQUE (UNIQUEA_AID, BS_BID)");
+
+ }
+
+ void assertSQLFragnment(List<String> list, String...keys) {
+ for (String sql : list) {
+ String SQL = sql.toUpperCase();
+ boolean matched = true;
+ for (String key : keys) {
+ String KEY = key.toUpperCase();
+ if (SQL.indexOf(KEY) == -1) {
+ matched = false;
+ break;
+ }
+ }
+ if (matched)
+ return;
+ }
+ int i = 0;
+ for (String sql : list) {
+ i++;
+ System.out.println(""+i+":"+sql);
+ }
+ fail("None of the above SQL contains all keys " + Arrays.toString(keys));
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java?rev=672038&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueA.java Thu Jun 26 15:04:06 2008
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import java.util.Collection;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.SecondaryTable;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+/**
+ * Data structures for testing unique constraint settings
+ * on ORM Annotatations.
+ *
+ * Unique columns must be non-nullable.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Table(name="UNIQUE_A",
+ uniqueConstraints={@UniqueConstraint(columnNames={"a1","a2"}),
+ @UniqueConstraint(columnNames={"a3","a4"})})
+@SecondaryTable(name="UNIQUE_SECONDARY",
+ uniqueConstraints=@UniqueConstraint(columnNames={"sa1"}))
+
+public class UniqueA {
+ @Id
+ private int aid;
+
+ @Column(unique=true, nullable=false)
+ private int a1;
+
+ @Column(nullable=false)
+ private int a2;
+
+ @Column(nullable=false)
+ private int a3;
+
+ @Column(nullable=false)
+ private int a4;
+
+
+ private int a5;
+ private int a6;
+
+ @Column(table="UNIQUE_SECONDARY", nullable=false)
+ private short sa1;
+ @Column(table="UNIQUE_SECONDARY")
+ private short sa2;
+
+ @ManyToMany
+ @JoinTable(name="UNIQUE_JOINTABLE",
+ uniqueConstraints=@UniqueConstraint(columnNames={"UNIQUEA_AID","BS_BID"}))
+ private Collection<UniqueB> bs;
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java?rev=672038&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/unique/UniqueB.java Thu Jun 26 15:04:06 2008
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.jdbc.unique;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name="UNIQUE_B",
+ uniqueConstraints={@UniqueConstraint(columnNames={"b1","b2"})})
+public class UniqueB {
+ @Id
+ @GeneratedValue(strategy=GenerationType.TABLE, generator="testGenerator")
+ @TableGenerator(name="testGenerator", table="UNIQUE_GENERATOR",
+ pkColumnName="GEN1", valueColumnName="GEN2",
+ uniqueConstraints={@UniqueConstraint(columnNames={"GEN1","GEN2"})})
+ private int bid;
+
+ @Column(nullable=false)
+ private int b1;
+ @Column(nullable=false)
+ private int b2;
+}