mirror of https://github.com/apache/openjpa.git
Modified handling of class level UniqueConstraints to be similar to field level constraints.
git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@495748 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
430d90f05f
commit
b7c7a47aac
|
@ -36,8 +36,6 @@ import org.apache.openjpa.jdbc.schema.ColumnIO;
|
||||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Schemas;
|
import org.apache.openjpa.jdbc.schema.Schemas;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
import org.apache.openjpa.jdbc.schema.Unique;
|
|
||||||
import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
|
|
||||||
import org.apache.openjpa.jdbc.sql.Joins;
|
import org.apache.openjpa.jdbc.sql.Joins;
|
||||||
import org.apache.openjpa.jdbc.sql.Result;
|
import org.apache.openjpa.jdbc.sql.Result;
|
||||||
import org.apache.openjpa.jdbc.sql.RowManager;
|
import org.apache.openjpa.jdbc.sql.RowManager;
|
||||||
|
@ -795,46 +793,11 @@ public class ClassMapping
|
||||||
_cols[i].setFlag(Column.FLAG_DIRECT_UPDATE, true);
|
_cols[i].setFlag(Column.FLAG_DIRECT_UPDATE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapUniqueConstraints();
|
// once columns are resolved, resolve unique constraints as they need
|
||||||
|
// the columns be resolved
|
||||||
|
_info.getUniques(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds unique constraints to the mapped table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void mapUniqueConstraints() {
|
|
||||||
Log log = getRepository().getLog();
|
|
||||||
Collection uniqueInfos = _info.getUniqueConstraints();
|
|
||||||
if (uniqueInfos == null || uniqueInfos.isEmpty())
|
|
||||||
return;
|
|
||||||
Iterator iter = uniqueInfos.iterator();
|
|
||||||
Table table = getTable();
|
|
||||||
int i = 1;
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
XMLSchemaParser.UniqueInfo uniqueInfo =
|
|
||||||
(XMLSchemaParser.UniqueInfo)iter.next();
|
|
||||||
if (uniqueInfo.cols == null || uniqueInfo.cols.isEmpty())
|
|
||||||
continue;
|
|
||||||
String constraintName = table.getName() + "_UNIQUE_" + i;
|
|
||||||
i++;
|
|
||||||
Unique uniqueConstraint = table.addUnique(constraintName);
|
|
||||||
Iterator uniqueColumnNames = uniqueInfo.cols.iterator();
|
|
||||||
while (uniqueColumnNames.hasNext()) {
|
|
||||||
String uniqueColumnName = (String)uniqueColumnNames.next();
|
|
||||||
Column uniqueColumn = table.getColumn(uniqueColumnName);
|
|
||||||
if (uniqueColumn != null) {
|
|
||||||
uniqueConstraint.addColumn(uniqueColumn);
|
|
||||||
} else {
|
|
||||||
table.removeUnique(uniqueConstraint);
|
|
||||||
if (log.isWarnEnabled())
|
|
||||||
log.warn(_loc.get("missing-unique-column", this,
|
|
||||||
table.getName(), uniqueColumnName));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve non-relation field mappings so that when we do relation
|
* Resolve non-relation field mappings so that when we do relation
|
||||||
* mappings they can rely on them for joins.
|
* mappings they can rely on them for joins.
|
||||||
|
@ -857,7 +820,7 @@ public class ClassMapping
|
||||||
fms[i].resolve(MODE_MAPPING);
|
fms[i].resolve(MODE_MAPPING);
|
||||||
|
|
||||||
_discrim.resolve(MODE_MAPPING);
|
_discrim.resolve(MODE_MAPPING);
|
||||||
_version.resolve(MODE_MAPPING);
|
_version.resolve(MODE_MAPPING);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initializeMapping() {
|
protected void initializeMapping() {
|
||||||
|
@ -986,7 +949,7 @@ public class ClassMapping
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
return assertStrategy().customLoad(sm, store, fetch, result);
|
return assertStrategy().customLoad(sm, store, fetch, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassStrategy assertStrategy() {
|
private ClassStrategy assertStrategy() {
|
||||||
if (_strategy == null)
|
if (_strategy == null)
|
||||||
throw new InternalException();
|
throw new InternalException();
|
||||||
|
|
|
@ -23,17 +23,19 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
|
import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
|
||||||
import org.apache.openjpa.jdbc.schema.Column;
|
import org.apache.openjpa.jdbc.schema.Column;
|
||||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Schema;
|
import org.apache.openjpa.jdbc.schema.Schema;
|
||||||
import org.apache.openjpa.jdbc.schema.SchemaGroup;
|
import org.apache.openjpa.jdbc.schema.SchemaGroup;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
|
import org.apache.openjpa.jdbc.schema.Unique;
|
||||||
import org.apache.openjpa.lib.meta.SourceTracker;
|
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.lib.xml.Commentable;
|
||||||
|
import org.apache.openjpa.util.UserException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about the mapping from a class to the schema, in raw form.
|
* Information about the mapping from a class to the schema, in raw form.
|
||||||
|
@ -47,6 +49,9 @@ public class ClassMappingInfo
|
||||||
extends MappingInfo
|
extends MappingInfo
|
||||||
implements SourceTracker, Commentable {
|
implements SourceTracker, Commentable {
|
||||||
|
|
||||||
|
private static final Localizer _loc = Localizer.forPackage
|
||||||
|
(ClassMappingInfo.class);
|
||||||
|
|
||||||
private String _className = Object.class.getName();
|
private String _className = Object.class.getName();
|
||||||
private String _tableName = null;
|
private String _tableName = null;
|
||||||
private boolean _joined = false;
|
private boolean _joined = false;
|
||||||
|
@ -55,7 +60,7 @@ public class ClassMappingInfo
|
||||||
private File _file = null;
|
private File _file = null;
|
||||||
private int _srcType = SRC_OTHER;
|
private int _srcType = SRC_OTHER;
|
||||||
private String[] _comments = null;
|
private String[] _comments = null;
|
||||||
private Collection _uniqueConstraints = null;//XMLSchemaParser.UniqueInfo
|
private Collection _uniques = null;//Unique
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The described class name.
|
* The described class name.
|
||||||
|
@ -313,21 +318,56 @@ public class ClassMappingInfo
|
||||||
_seconds.put(key, cinfo._seconds.get(key));
|
_seconds.put(key, cinfo._seconds.get(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cinfo._uniqueConstraints != null)
|
if (cinfo._uniques != null)
|
||||||
_uniqueConstraints = new ArrayList(cinfo._uniqueConstraints);
|
_uniques = new ArrayList(cinfo._uniques);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUniqueConstaint(String[] columnNames) {
|
public void addUnique(String name, String[] columnNames) {
|
||||||
if (_uniqueConstraints == null)
|
if (columnNames == null || columnNames.length == 0)
|
||||||
_uniqueConstraints = new ArrayList();
|
return;
|
||||||
XMLSchemaParser.UniqueInfo uniqueInfo = new XMLSchemaParser.UniqueInfo();
|
if (_uniques == null)
|
||||||
uniqueInfo.cols = Arrays.asList(columnNames);
|
_uniques = new ArrayList();
|
||||||
_uniqueConstraints.add(uniqueInfo);
|
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",
|
||||||
|
getClassName()));
|
||||||
|
Column column = new Column();
|
||||||
|
column.setName(columnNames[i]);
|
||||||
|
uniqueConstraint.addColumn(column);
|
||||||
|
}
|
||||||
|
_uniques.add(uniqueConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection getUniqueConstraints() {
|
public Unique[] getUniques(ClassMapping cm, boolean adapt) {
|
||||||
return _uniqueConstraints;
|
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);
|
||||||
|
}
|
||||||
|
return (Unique[])result.toArray(new Unique[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
public File getSourceFile() {
|
public File getSourceFile() {
|
||||||
return _file;
|
return _file;
|
||||||
|
|
|
@ -401,6 +401,9 @@ untraversable-path: Result path "{2}" in result type "{1}" of mapping "{0}" \
|
||||||
attempts to traverse through a non-relation field.
|
attempts to traverse through a non-relation field.
|
||||||
num-cols-path: Result path "{2}" in result type "{1}" of mapping "{0}" \
|
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.
|
attempts to map a field that does not have exactly 1 column.
|
||||||
missing-unique-column: A unique constraint includes a column "{2}" specified \
|
missing-unique-column: A unique constraint specified in mapping of class "{0}" \
|
||||||
in mapping of class "{0}" to table "{1}". However, the column does not \
|
to table "{1}" includes a column "{2}". However, the column does not \
|
||||||
exist in "{1}" table. This constraint will not be defined in the schema.
|
exist in "{1}" table.
|
||||||
|
empty-unique-column: A unique constraint specified in mapping of class "{0}" \
|
||||||
|
includes an empty column "{2}".
|
||||||
|
|
|
@ -461,7 +461,8 @@ public class AnnotationPersistenceMappingParser
|
||||||
cm.getMappingInfo().setTableName(tableName);
|
cm.getMappingInfo().setTableName(tableName);
|
||||||
|
|
||||||
for (UniqueConstraint unique:table.uniqueConstraints()) {
|
for (UniqueConstraint unique:table.uniqueConstraints()) {
|
||||||
((ClassMappingInfo)cm.getMappingInfo()).addUniqueConstaint(unique.columnNames());
|
((ClassMappingInfo)cm.getMappingInfo())
|
||||||
|
.addUnique(null, unique.columnNames());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue