We need to look for FTI declarations in superclasses, too, just as we already do with @Entity indexes and @Table unique constraints. Ripped out the pointless RecordMetaData while I was at it. This is a lot cleaner.
This commit is contained in:
@@ -71,6 +71,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
public DepotMarshaller (Class<T> pclass, PersistenceContext context)
|
public DepotMarshaller (Class<T> pclass, PersistenceContext context)
|
||||||
{
|
{
|
||||||
_pclass = pclass;
|
_pclass = pclass;
|
||||||
|
|
||||||
Entity entity = pclass.getAnnotation(Entity.class);
|
Entity entity = pclass.getAnnotation(Entity.class);
|
||||||
|
|
||||||
// see if this is a computed entity
|
// see if this is a computed entity
|
||||||
@@ -95,14 +96,6 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
context.tableGenerators.put(generator.name(), generator);
|
context.tableGenerators.put(generator.name(), generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are FTS indexes in the Table, map those out here for future use
|
|
||||||
Table table = pclass.getAnnotation(Table.class);
|
|
||||||
if (table != null) {
|
|
||||||
for (FullTextIndex fts : table.fullTextIndexes()) {
|
|
||||||
_fullTextIndexes.put(fts.name(), fts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean seenIdentityGenerator = false;
|
boolean seenIdentityGenerator = false;
|
||||||
|
|
||||||
// introspect on the class and create marshallers for persistent fields
|
// introspect on the class and create marshallers for persistent fields
|
||||||
@@ -188,6 +181,49 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
|
|
||||||
// generate our full list of fields/columns for use in queries
|
// generate our full list of fields/columns for use in queries
|
||||||
_allFields = fields.toArray(new String[fields.size()]);
|
_allFields = fields.toArray(new String[fields.size()]);
|
||||||
|
|
||||||
|
// now check for @Entity and @Table annotations on the entire superclass chain
|
||||||
|
Class<?> iterClass = pclass;
|
||||||
|
do {
|
||||||
|
Table table = iterClass.getAnnotation(Table.class);
|
||||||
|
if (table != null) {
|
||||||
|
for (UniqueConstraint constraint : table.uniqueConstraints()) {
|
||||||
|
String[] conFields = constraint.fieldNames();
|
||||||
|
Set<String> colSet = new HashSet<String>();
|
||||||
|
for (int ii = 0; ii < conFields.length; ii ++) {
|
||||||
|
FieldMarshaller fm = _fields.get(conFields[ii]);
|
||||||
|
if (fm == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unknown unique constraint field: " + conFields[ii]);
|
||||||
|
}
|
||||||
|
colSet.add(fm.getColumnName());
|
||||||
|
}
|
||||||
|
_uniqueConstraints.add(colSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are FTS indexes in the Table, map those out here for future use
|
||||||
|
for (FullTextIndex fti : table.fullTextIndexes()) {
|
||||||
|
if (_fullTextIndexes.containsKey(fti.name())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_fullTextIndexes.put(fti.name(), fti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = iterClass.getAnnotation(Entity.class);
|
||||||
|
if (entity != null) {
|
||||||
|
for (Index index : entity.indices()) {
|
||||||
|
if (_indexes.containsKey(index.name())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_indexes.put(index.name(), index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterClass = iterClass.getSuperclass();
|
||||||
|
|
||||||
|
} while (PersistentRecord.class.isAssignableFrom(iterClass) &&
|
||||||
|
!PersistentRecord.class.equals(iterClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -532,18 +568,15 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
// fetch all relevant information regarding our table from the database
|
// fetch all relevant information regarding our table from the database
|
||||||
TableMetaData metaData = TableMetaData.load(ctx, getTableName());
|
TableMetaData metaData = TableMetaData.load(ctx, getTableName());
|
||||||
|
|
||||||
// compute relevant information from our persistent record, too
|
|
||||||
RecordMetaData rMeta = new RecordMetaData(_pclass, _fields);
|
|
||||||
|
|
||||||
// if the table does not exist, create it
|
// if the table does not exist, create it
|
||||||
if (!metaData.tableExists) {
|
if (!metaData.tableExists) {
|
||||||
final String[] fDeclarations = declarations;
|
final String[] fDeclarations = declarations;
|
||||||
final String[][] uniqueConCols = new String[rMeta.uniqueConstraints.size()][];
|
final String[][] uniqueConCols = new String[_uniqueConstraints.size()][];
|
||||||
int kk = 0;
|
int kk = 0;
|
||||||
for (Set<String> colSet : rMeta.uniqueConstraints) {
|
for (Set<String> colSet : _uniqueConstraints) {
|
||||||
uniqueConCols[kk++] = colSet.toArray(new String[colSet.size()]);
|
uniqueConCols[kk++] = colSet.toArray(new String[colSet.size()]);
|
||||||
}
|
}
|
||||||
final Iterable<Index> indexen = rMeta.indices.values();
|
final Iterable<Index> indexen = _indexes.values();
|
||||||
ctx.invoke(new Modifier() {
|
ctx.invoke(new Modifier() {
|
||||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||||
// create the table
|
// create the table
|
||||||
@@ -694,7 +727,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add any named indices that exist on the record but not yet on the table
|
// add any named indices that exist on the record but not yet on the table
|
||||||
for (final Index index : rMeta.indices.values()) {
|
for (final Index index : _indexes.values()) {
|
||||||
final String ixName = getTableName() + "_" + index.name();
|
final String ixName = getTableName() + "_" + index.name();
|
||||||
if (metaData.indexColumns.containsKey(ixName)) {
|
if (metaData.indexColumns.containsKey(ixName)) {
|
||||||
// this index already exists
|
// this index already exists
|
||||||
@@ -716,7 +749,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
Set<Set<String>> uniqueIndices = new HashSet<Set<String>>(metaData.indexColumns.values());
|
Set<Set<String>> uniqueIndices = new HashSet<Set<String>>(metaData.indexColumns.values());
|
||||||
|
|
||||||
// unique constraints are unordered and may be unnamed, so we view them only as column sets
|
// unique constraints are unordered and may be unnamed, so we view them only as column sets
|
||||||
for (Set<String> colSet : rMeta.uniqueConstraints) {
|
for (Set<String> colSet : _uniqueConstraints) {
|
||||||
if (uniqueIndices.contains(colSet)) {
|
if (uniqueIndices.contains(colSet)) {
|
||||||
// the table already contains precisely this column set
|
// the table already contains precisely this column set
|
||||||
continue;
|
continue;
|
||||||
@@ -905,51 +938,6 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class RecordMetaData
|
|
||||||
{
|
|
||||||
public Map<String, Index> indices = new HashMap<String, Index>();
|
|
||||||
public Set<Set<String>> uniqueConstraints = new HashSet<Set<String>>();
|
|
||||||
|
|
||||||
public RecordMetaData (Class<?> pClass, Map<String, FieldMarshaller> fmap)
|
|
||||||
{
|
|
||||||
recurse(pClass, fmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void recurse (Class<?> pClass, Map<String, FieldMarshaller> fmap)
|
|
||||||
{
|
|
||||||
// recurse first so subclass definitions overwrite superclass ones
|
|
||||||
Class<?> superClass = pClass.getSuperclass();
|
|
||||||
if (PersistentRecord.class.isAssignableFrom(superClass) &&
|
|
||||||
!PersistentRecord.class.equals(superClass)) {
|
|
||||||
recurse(superClass, fmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
Table table = pClass.getAnnotation(Table.class);
|
|
||||||
if (table != null) {
|
|
||||||
for (UniqueConstraint constraint : table.uniqueConstraints()) {
|
|
||||||
String[] fields = constraint.fieldNames();
|
|
||||||
Set<String> colSet = new HashSet<String>();
|
|
||||||
for (int ii = 0; ii < fields.length; ii ++) {
|
|
||||||
FieldMarshaller fm = fmap.get(fields[ii]);
|
|
||||||
if (fm == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unknown unique constraint field: " + fields[ii]);
|
|
||||||
}
|
|
||||||
colSet.add(fm.getColumnName());
|
|
||||||
}
|
|
||||||
uniqueConstraints.add(colSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity entity = pClass.getAnnotation(Entity.class);
|
|
||||||
if (entity != null) {
|
|
||||||
for (Index index : entity.indices()) {
|
|
||||||
indices.put(index.name(), index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The persistent object class that we manage. */
|
/** The persistent object class that we manage. */
|
||||||
protected Class<T> _pclass;
|
protected Class<T> _pclass;
|
||||||
|
|
||||||
@@ -975,7 +963,12 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
/** The fields of our object with directly corresponding table columns. */
|
/** The fields of our object with directly corresponding table columns. */
|
||||||
protected String[] _columnFields;
|
protected String[] _columnFields;
|
||||||
|
|
||||||
/** A mapping of all of the full text index annotations for our persistent record. */
|
/** The indexes defined in @Entity annotations for this record. */
|
||||||
|
protected Map<String, Index> _indexes = new HashMap<String, Index>();
|
||||||
|
|
||||||
|
/** The unique constraints defined in @Table annotations for this record. */
|
||||||
|
protected Set<Set<String>> _uniqueConstraints = new HashSet<Set<String>>();
|
||||||
|
|
||||||
protected Map<String, FullTextIndex> _fullTextIndexes = new HashMap<String, FullTextIndex>();
|
protected Map<String, FullTextIndex> _fullTextIndexes = new HashMap<String, FullTextIndex>();
|
||||||
|
|
||||||
/** The version of our persistent object schema as specified in the class definition. */
|
/** The version of our persistent object schema as specified in the class definition. */
|
||||||
|
|||||||
Reference in New Issue
Block a user