diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
index 1974aeea2..52897c274 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
@@ -24,11 +24,13 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
+import java.util.HashMap;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.schema.Schema;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
@@ -77,7 +79,7 @@ public class TableJDBCSeq
private transient Log _log = null;
private int _alloc = 50;
private int _intValue = 1;
- private final Status _stat = new Status();
+ private final HashMap _stat = new HashMap();
private String _table = "OPENJPA_SEQUENCE_TABLE";
private String _seqColumnName = "SEQUENCE_VALUE";
@@ -85,6 +87,7 @@ public class TableJDBCSeq
private Column _seqColumn = null;
private Column _pkColumn = null;
+ private int _schemasIdx = 0;
/**
* The sequence table name. Defaults to OPENJPA_SEQUENCE_TABLE
.
@@ -212,20 +215,37 @@ public class TableJDBCSeq
buildTable();
}
+
public void addSchema(ClassMapping mapping, SchemaGroup group) {
- // table already exists?
- if (group.isKnownTable(_table))
- return;
+ // Since the table is created by openjpa internally
+ // we can create the table for each schema within the PU
+ // in here.
+
+ Schema[] schemas = group.getSchemas();
+ for (int i = 0; i < schemas.length; i++) {
+ String schemaName = Strings.getPackageName(_table);
+ if (schemaName.length() == 0)
+ schemaName = Schemas.getNewTableSchema(_conf);
+ if (schemaName == null)
+ schemaName = schemas[i].getName();
- String schemaName = Strings.getPackageName(_table);
- if (schemaName.length() == 0)
- schemaName = Schemas.getNewTableSchema(_conf);
-
- // create table in this group
- Schema schema = group.getSchema(schemaName);
- if (schema == null)
- schema = group.addSchema(schemaName);
- schema.importTable(_pkColumn.getTable());
+ // create table in this group
+ Schema schema = group.getSchema(schemaName);
+ if (schema == null)
+ schema = group.addSchema(schemaName);
+
+ schema.importTable(_pkColumn.getTable());
+ // build the index for the sequence tables
+ // the index name will the fully qualified table name +_IDX
+ Table tab = schema.getTable(_table);
+ Index idx = tab.addIndex(tab.getFullName()+"_IDX");
+ idx.setUnique(true);
+ // we need to reset the table name in the column with the
+ // fully qualified name for matching the table name from the
+ // Column.
+ _pkColumn.resetTableName(schemaName+"."+_pkColumn.getTableName());
+ idx.addColumn(_pkColumn);
+ }
}
protected Object nextInternal(JDBCStore store, ClassMapping mapping)
@@ -285,8 +305,14 @@ public class TableJDBCSeq
* Return the appropriate status object for the given class, or null
* if cannot handle the given class. The mapping may be null.
*/
- protected Status getStatus(ClassMapping mapping) {
- return _stat;
+ protected Status getStatus(ClassMapping mapping) {
+ Status status = (Status)_stat.get(mapping);
+ if (status == null){
+ status = new Status();
+ _stat.put(mapping, status);
+ }
+ return status;
+
}
/**
@@ -392,8 +418,9 @@ public class TableJDBCSeq
getClass(), mapping));
DBDictionary dict = _conf.getDBDictionaryInstance();
+ String tableName = resolveTableName(mapping, _pkColumn.getTable());
SQLBuffer insert = new SQLBuffer(dict).append("INSERT INTO ").
- append(_pkColumn.getTable()).append(" (").
+ append(tableName).append(" (").
append(_pkColumn).append(", ").append(_seqColumn).
append(") VALUES (").
appendValue(pk, _pkColumn).append(", ").
@@ -431,7 +458,8 @@ public class TableJDBCSeq
SQLBuffer sel = new SQLBuffer(dict).append(_seqColumn);
SQLBuffer where = new SQLBuffer(dict).append(_pkColumn).append(" = ").
appendValue(pk, _pkColumn);
- SQLBuffer tables = new SQLBuffer(dict).append(_seqColumn.getTable());
+ String tableName = resolveTableName(mapping, _seqColumn.getTable());
+ SQLBuffer tables = new SQLBuffer(dict).append(tableName);
SQLBuffer select = dict.toSelect(sel, null, tables, where, null,
null, null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE);
@@ -467,7 +495,7 @@ public class TableJDBCSeq
throw new InvalidStateException(_loc.get("bad-seq-type",
getClass(), mapping));
- DBDictionary dict = _conf.getDBDictionaryInstance();
+ DBDictionary dict = _conf.getDBDictionaryInstance();
SQLBuffer where = new SQLBuffer(dict).append(_pkColumn).append(" = ").
appendValue(pk, _pkColumn);
@@ -486,7 +514,8 @@ public class TableJDBCSeq
// update the value
upd = new SQLBuffer(dict);
- upd.append("UPDATE ").append(_seqColumn.getTable()).
+ String tableName = resolveTableName(mapping, _seqColumn.getTable());
+ upd.append("UPDATE ").append(tableName).
append(" SET ").append(_seqColumn).append(" = ").
appendValue(Numbers.valueOf(cur + inc), _seqColumn).
append(" WHERE ").append(where).append(" AND ").
@@ -503,7 +532,7 @@ public class TableJDBCSeq
}
}
- // setup new sequence range
+ // setup new sequence range
synchronized (stat) {
if (updateStatSeq && stat.seq < cur)
stat.seq = cur;
@@ -512,6 +541,21 @@ public class TableJDBCSeq
}
return true;
}
+ /**
+ * Resolve a fully qualified table name
+ *
+ * @param class
+ * mapping to get the schema name
+ */
+ public String resolveTableName(ClassMapping mapping, Table table) {
+ String sName = mapping.getTable().getSchemaName();
+ String tableName;
+ if (sName == null)
+ tableName = table.getFullName();
+ else
+ tableName = sName + "." + table.getFullName();
+ return tableName;
+ }
/**
* Creates the sequence table in the DB.
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java
index 77f0133ba..deda088e8 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java
@@ -180,6 +180,14 @@ public class Column
_tableName = name;
_fullName = null;
}
+
+ /**
+ * Reset the table name with the fully qualified table name which
+ * includes the schema name
+ */
+ public void resetTableName(String name) {
+ _tableName = name;
+ }
/**
* The column's schema name.
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
index 683b8c6cf..c68a674b7 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
@@ -93,11 +93,6 @@ public abstract class LocalConstraint
* Add a column to the constraint.
*/
public void addColumn(Column col) {
- if (col == null || !ObjectUtils.equals(col.getTable(), getTable()))
- throw new InvalidStateException(_loc.get("table-mismatch",
- col == null ? null : col.getTable(),
- col == null ? null : getTable()));
-
if (_colList == null)
_colList = new ArrayList(3);
else if (_colList.contains(col))
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java
index e9e478e46..a5d7fd3f3 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java
@@ -186,6 +186,42 @@ public class SchemaGroup
return null;
}
+ /**
+ * Find the table with the given name in the group, using '.' as the catalog
+ * separator. Returns null if no table found.
+ */
+ public Table findTable(Schema inSchema, String name) {
+ if (name == null)
+ return null;
+
+ int dotIdx = name.indexOf('.');
+ if (dotIdx != -1) {
+ String schemaName = name.substring(0, dotIdx);
+ name = name.substring(dotIdx + 1);
+ Schema schema = getSchema(schemaName);
+ if (schema != null)
+ return schema.getTable(name);
+ } else {
+ Schema[] schemas = getSchemas();
+ for (int i = 0; i < schemas.length; i++) {
+ Table tab = schemas[i].getTable(name);
+ // if a table is found and it has the same schema
+ // as the input schema , it means that the table
+ // exists. However, if the input schema is null,
+ // then we assume that there is only one table for the
+ // db default schema, in this case, table exists..
+ // We can't handle the case that one entity has schema name
+ // and other entity does not have schema name but both entities
+ // map to the same table.
+ if (tab != null
+ && (schemas[i] == inSchema || inSchema.getName() == null))
+ return tab;
+
+ }
+ }
+ return null;
+ }
+
/**
* Return true if the given sequence is known to exist. While
* {@link #findSequence} may exhibit dynamic behavior in some schema group
@@ -242,8 +278,37 @@ public class SchemaGroup
}
/**
- * Find all foreign keys exported by a given primary key (all foreign
- * keys that link to the primary key).
+ * Find the sequence with the given name in the group, using '.' as the
+ * catalog separator. Returns null if no sequence found.
+ */
+ public Sequence findSequence(Schema inSchema, String name) {
+ if (name == null)
+ return null;
+
+ int dotIdx = name.indexOf('.');
+ if (dotIdx != -1) {
+ String schemaName = name.substring(0, dotIdx);
+ name = name.substring(dotIdx + 1);
+ Schema schema = getSchema(schemaName);
+ if (schema != null)
+ return schema.getSequence(name);
+ } else {
+ Schema[] schemas = getSchemas();
+ Sequence seq;
+ for (int i = 0; i < schemas.length; i++) {
+ seq = schemas[i].getSequence(name);
+ if ((seq != null)
+ && (schemas[i] == inSchema || inSchema.getName() == null))
+ return seq;
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Find all foreign keys exported by a given primary key (all foreign keys
+ * that link to the primary key).
*/
public ForeignKey[] findExportedForeignKeys(PrimaryKey pk) {
if (pk == null)
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java
index 131186fae..199b624d4 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java
@@ -450,7 +450,7 @@ public class SchemaTool {
for (int i = 0; i < schemas.length; i++) {
seqs = schemas[i].getSequences();
for (int j = 0; j < seqs.length; j++) {
- if (db.findSequence(seqs[j]) != null)
+ if (db.findSequence(schemas[i], seqs[j].getFullName()) != null)
continue;
if (createSequence(seqs[j])) {
@@ -473,7 +473,7 @@ public class SchemaTool {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
cols = tabs[j].getColumns();
- dbTable = db.findTable(tabs[j]);
+ dbTable = db.findTable(schemas[i], tabs[j].getFullName());
for (int k = 0; k < cols.length; k++) {
if (dbTable != null) {
col = dbTable.getColumn(cols[k].getName());
@@ -500,7 +500,7 @@ public class SchemaTool {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
pk = tabs[j].getPrimaryKey();
- dbTable = db.findTable(tabs[j]);
+ dbTable = db.findTable(schemas[i], tabs[j].getFullName());
if (pk != null && !pk.isLogical() && dbTable != null) {
if (dbTable.getPrimaryKey() == null
&& addPrimaryKey(pk))
@@ -520,7 +520,7 @@ public class SchemaTool {
for (int i = 0; i < schemas.length; i++) {
tabs = schemas[i].getTables();
for (int j = 0; j < tabs.length; j++) {
- if (db.findTable(tabs[j]) != null)
+ if (db.findTable(schemas[i], tabs[j].getFullName()) != null)
continue;
if (createTable(tabs[j])) {
@@ -546,7 +546,7 @@ public class SchemaTool {
continue;
idxs = tabs[j].getIndexes();
- dbTable = db.findTable(tabs[j]);
+ dbTable = db.findTable(schemas[i], tabs[j].getFullName());
for (int k = 0; k < idxs.length; k++) {
if (dbTable != null) {
idx = findIndex(dbTable, idxs[k]);
@@ -596,7 +596,7 @@ public class SchemaTool {
continue;
fks = tabs[j].getForeignKeys();
- dbTable = db.findTable(tabs[j]);
+ dbTable = db.findTable(schemas[i],tabs[j].getFullName());
for (int k = 0; k < fks.length; k++) {
if (!fks[k].isLogical() && dbTable != null) {
fk = findForeignKey(dbTable, fks[k]);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
index ebf1f4066..926cccf14 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Table.java
@@ -498,7 +498,7 @@ public class Table
* Return the table's indexes.
*/
public Index[] getIndexes() {
- if (_idxs == null)
+ if (_idxs == null || _idxs.length == 0)
_idxs = (_idxMap == null) ? Schemas.EMPTY_INDEXES : (Index[])
_idxMap.values().toArray(new Index[_idxMap.size()]);
return _idxs;
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog1.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog1.java
new file mode 100644
index 000000000..b6ee13c95
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog1.java
@@ -0,0 +1,96 @@
+/*
+ * 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.generationtype;
+
+import javax.persistence.*;
+import java.io.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "Dog1")
+@Table(name = "DOGTAB", schema = "SCHEMA1")
+@IdClass(DogId.class)
+public class Dog1 implements Serializable
+
+{
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private int id2;
+
+ @Id
+ private int datastoreid;
+
+ private String name;
+
+ private float price;
+
+ private boolean domestic;
+
+ public Dog1() {
+ super();
+
+ }
+
+ public Dog1(String name) {
+ this.id2 = id2;
+ this.name = name;
+
+ }
+
+ public int getId2() {
+ return id2;
+ }
+
+ public void setId2(int id) {
+ this.id2 = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getPrice() {
+ return price;
+ }
+
+ public void setPrice(float price) {
+ this.price = price;
+ }
+
+ public boolean isDomestic() {
+ return domestic;
+ }
+
+ public void setDomestic(boolean domestic) {
+ this.domestic = domestic;
+ }
+
+ public int getDatastoreid() {
+ return datastoreid;
+ }
+
+ public void setDatastoreid(int datastoreid) {
+ this.datastoreid = datastoreid;
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog2.java
new file mode 100644
index 000000000..9e7c5656a
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/Dog2.java
@@ -0,0 +1,96 @@
+/*
+ * 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.generationtype;
+
+import javax.persistence.*;
+import java.io.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "Dog2")
+@Table(name = "DOGTAB", schema = "SCHEMA2")
+@IdClass(DogId.class)
+public class Dog2 implements Serializable
+
+{
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private int id2;
+
+ @Id
+ private int datastoreid;
+
+ private String name;
+
+ private float price;
+
+ private boolean domestic;
+
+ public Dog2() {
+ super();
+
+ }
+
+ public Dog2(String name) {
+ this.id2 = id2;
+ this.name = name;
+
+ }
+
+ public int getId2() {
+ return id2;
+ }
+
+ public void setId2(int id) {
+ this.id2 = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getPrice() {
+ return price;
+ }
+
+ public void setPrice(float price) {
+ this.price = price;
+ }
+
+ public boolean isDomestic() {
+ return domestic;
+ }
+
+ public void setDomestic(boolean domestic) {
+ this.domestic = domestic;
+ }
+
+ public int getDatastoreid() {
+ return datastoreid;
+ }
+
+ public void setDatastoreid(int datastoreid) {
+ this.datastoreid = datastoreid;
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogId.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogId.java
new file mode 100644
index 000000000..f7d68629d
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogId.java
@@ -0,0 +1,103 @@
+/*
+ * 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.generationtype;
+
+
+import java.io.*;
+
+/**
+ * Application identity class for: tutorial.ejb.Animal
+ *
+ * Auto-generated by: org.apache.openjpa.enhance.ApplicationIdTool
+ */
+public class DogId implements Serializable {
+ static {
+ // register persistent class in JVM
+ try {
+ Class.forName("tutorial.ejb.Dog");
+ } catch (Exception e) {
+ }
+ }
+
+ public int id2;
+
+ public int datastoreid;
+
+ public DogId() {
+ }
+
+ public DogId(String str) {
+ fromString(str);
+ }
+
+ public String toString() {
+ return String.valueOf(id2) + "::" + datastoreid;
+ }
+
+ public int hashCode() {
+ int rs = 17;
+ rs = rs * 37 + (int) (id2 ^ (id2 >>> 32));
+ rs = rs
+ * 37
+ + ((datastoreid == 0) ? 0 : new Integer(datastoreid).hashCode());
+ return rs;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null || obj.getClass() != getClass())
+ return false;
+
+ DogId other = (DogId) obj;
+ return (id2 == other.id2)
+ && ((datastoreid == 0 && other.datastoreid == 0) || (datastoreid != 0 && datastoreid == other.datastoreid));
+ }
+
+ private void fromString(String str) {
+ Tokenizer toke = new Tokenizer(str);
+ str = toke.nextToken();
+ id2 = Integer.parseInt(str);
+ str = toke.nextToken();
+ datastoreid = Integer.parseInt(str);
+ }
+
+ protected static class Tokenizer {
+ private final String str;
+
+ private int last;
+
+ public Tokenizer(String str) {
+ this.str = str;
+ }
+
+ public String nextToken() {
+ int next = str.indexOf("::", last);
+ String part;
+ if (next == -1) {
+ part = str.substring(last);
+ last = str.length();
+ } else {
+ part = str.substring(last, next);
+ last = next + 2;
+ }
+ return part;
+ }
+ }
+}
\ No newline at end of file
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable.java
new file mode 100644
index 000000000..537ccec76
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable.java
@@ -0,0 +1,101 @@
+/*
+ * 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.generationtype;
+
+
+import javax.persistence.*;
+import java.io.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "DogTable")
+@Table(name = "DOGTABLE", schema = "SCHEMA1")
+@IdClass(DogId.class)
+public class DogTable implements Serializable
+
+{
+ @Id
+ @TableGenerator(name = "Dog_Gen1", table = "ID_Gen1",
+ pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL",
+ pkColumnValue = "ID2", initialValue = 20, allocationSize = 10)
+ @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen1")
+ private int id2;
+
+ @Id
+ private int datastoreid;
+
+ private String name;
+
+ private float price;
+
+ private boolean domestic;
+
+ public DogTable() {
+ super();
+
+ }
+
+ public DogTable(String name) {
+ this.id2 = id2;
+ this.name = name;
+
+ }
+
+ public int getId2() {
+ return id2;
+ }
+
+ public void setId2(int id) {
+ this.id2 = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getPrice() {
+ return price;
+ }
+
+ public void setPrice(float price) {
+
+ this.price = price;
+ }
+
+ public boolean isDomestic() {
+ return domestic;
+ }
+
+ public void setDomestic(boolean domestic) {
+ this.domestic = domestic;
+ }
+
+ public int getDatastoreid() {
+ return datastoreid;
+ }
+
+ public void setDatastoreid(int datastoreid) {
+ this.datastoreid = datastoreid;
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable2.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable2.java
new file mode 100644
index 000000000..4ddf69e5b
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/DogTable2.java
@@ -0,0 +1,100 @@
+/*
+ * 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.generationtype;
+
+import java.io.*;
+import javax.persistence.*;
+
+/**
+ * Extension of Animal class illustrating inheritance.
+ */
+@Entity(name = "DogTable2")
+@Table(name = "DOGTABLE", schema = "SCHEMA2")
+@IdClass(DogId.class)
+public class DogTable2 implements Serializable
+
+{
+ @Id
+ @TableGenerator(name = "Dog_Gen2", table = "ID_Gen2",
+ pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL",
+ pkColumnValue = "ID2", initialValue = 100, allocationSize = 10)
+ @GeneratedValue(strategy = GenerationType.TABLE, generator = "Dog_Gen2")
+ private int id2;
+
+ @Id
+ private int datastoreid;
+
+ private String name;
+
+ private float price;
+
+ private boolean domestic;
+
+ public DogTable2() {
+ super();
+
+ }
+
+ public DogTable2(String name) {
+ this.id2 = id2;
+ this.name = name;
+
+ }
+
+ public int getId2() {
+ return id2;
+ }
+
+ public void setId2(int id) {
+ this.id2 = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getPrice() {
+ return price;
+ }
+
+ public void setPrice(float price) {
+
+ this.price = price;
+ }
+
+ public boolean isDomestic() {
+ return domestic;
+ }
+
+ public void setDomestic(boolean domestic) {
+ this.domestic = domestic;
+ }
+
+ public int getDatastoreid() {
+ return datastoreid;
+ }
+
+ public void setDatastoreid(int datastoreid) {
+ this.datastoreid = datastoreid;
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestMultipleSchemaNames.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestMultipleSchemaNames.java
new file mode 100644
index 000000000..c3a44c4ed
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/generationtype/TestMultipleSchemaNames.java
@@ -0,0 +1,237 @@
+/*
+ * 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.generationtype;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestMultipleSchemaNames extends SingleEMFTestCase {
+ public void setUp() {
+ setUp(Dog1.class, Dog2.class, DogTable.class, DogTable2.class);
+
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ // cleanup database first
+ Query qry = em.createQuery("select d from Dog1 d");
+ List result = qry.getResultList();
+
+ for (int index = 0; index < result.size(); index++) {
+ Dog1 Obj = (Dog1) result.get(index);
+ em.remove(Obj);
+ }
+ Query qry2 = em.createQuery("select d from Dog2 d");
+ List result2 = qry2.getResultList();
+
+ for (int index = 0; index < result2.size(); index++) {
+ Dog2 Obj = (Dog2) result2.get(index);
+ em.remove(Obj);
+ }
+ Query qry3 = em.createQuery("select d from DogTable d");
+ List result3 = qry3.getResultList();
+
+ for (int index = 0; index < result3.size(); index++) {
+ DogTable Obj = (DogTable) result3.get(index);
+ em.remove(Obj);
+ }
+ Query qry4 = em.createQuery("select d from DogTable2 d");
+ List result4 = qry4.getResultList();
+
+ for (int index = 0; index < result4.size(); index++) {
+ DogTable2 Obj = (DogTable2) result4.get(index);
+ em.remove(Obj);
+ }
+
+ Query delschema1 = em
+ .createNativeQuery("delete from schema1.openjpa_sequence_table");
+ delschema1.executeUpdate();
+ Query delschema2 = em
+ .createNativeQuery("delete from schema2.openjpa_sequence_table");
+ delschema2.executeUpdate();
+ Query delgentable = em.createNativeQuery("delete from schema1.id_gen1");
+ delgentable.executeUpdate();
+ Query delgentable2 = em
+ .createNativeQuery("delete from schema2.id_gen2");
+ delgentable2.executeUpdate();
+
+ em.getTransaction().commit();
+
+ }
+
+ public void testGeneratedAUTO() {
+ EntityManager em = emf.createEntityManager();
+ OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+ em.getTransaction().begin();
+
+ Dog1 dog1 = new Dog1();
+ dog1.setName("helloDog1");
+ dog1.setDatastoreid(12);
+ dog1.setPrice(12000);
+
+ em.persist(dog1);
+ Dog1 dog1a = new Dog1();
+ dog1a.setName("helloDog2");
+ dog1a.setDatastoreid(15);
+ dog1a.setPrice(22000);
+ em.persist(dog1a);
+ // add dog2
+ Dog2 dog2 = new Dog2();
+ dog2.setName("helloDog3");
+ dog2.setDatastoreid(12);
+ dog2.setPrice(15000);
+ em.persist(dog2);
+
+ Dog2 dog2a = new Dog2();
+ dog2a.setName("helloDog4");
+ dog2a.setDatastoreid(19);
+ dog2a.setPrice(25000);
+ em.persist(dog2a);
+ em.getTransaction().commit();
+ // System.out.println("persist dogs are done");
+
+ Dog1 dog1x = em.find(Dog1.class, kem.getObjectId(dog1));
+ assertTrue(dog1x.getId2() == 1 || dog1x.getId2() == 2);
+ assertEquals(dog1x.getName(), "helloDog1");
+ dog1x.setName("Dog1");
+ dog1x.setDomestic(true);
+ Dog1 dog11 = em.find(Dog1.class, kem.getObjectId(dog1a));
+ assertTrue(dog11.getId2() == 1 || dog11.getId2() == 2);
+ assertEquals(dog11.getName(), "helloDog2");
+ dog11.setName("Dog2");
+ dog11.setDomestic(true);
+ // update dog2
+ Dog2 dog2x = em.find(Dog2.class, kem.getObjectId(dog2));
+ assertTrue(dog2x.getId2() == 1 || dog2x.getId2() == 2);
+ assertEquals(dog2x.getName(), "helloDog3");
+ dog2x.setName("Dog3");
+ dog2x.setDomestic(true);
+ Dog2 dog21 = em.find(Dog2.class, kem.getObjectId(dog2a));
+ assertTrue(dog21.getId2() == 1 || dog21.getId2() == 2);
+ assertEquals(dog21.getName(), "helloDog4");
+ dog21.setName("Dog4");
+ dog21.setDomestic(true);
+
+ // get the update dog name
+
+ em.getTransaction().begin();
+ Query qry1 = em.createQuery("select d from Dog1 d order by d.name");
+ List result1 = qry1.getResultList();
+ for (int index = 0; index < result1.size(); index++) {
+ Dog1 dog4 = (Dog1) result1.get(index);
+ int i = index + 1;
+ assertTrue(dog4.getId2() == 1 || dog4.getId2() == 2);
+ assertEquals(dog4.getName(), "Dog" + i);
+ }
+
+ Query qry2 = em.createQuery("select d from Dog2 d order by d.name");
+ List result2 = qry2.getResultList();
+
+ for (int index = 0; index < result2.size(); index++) {
+ Dog2 dog5 = (Dog2) result2.get(index);
+ assertTrue(dog5.getId2() == 1 || dog5.getId2() == 2);
+ int j = index + 3;
+ assertEquals(dog5.getName(), "Dog" + j);
+ }
+
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public void testGeneratedTABLE() {
+ EntityManager em = emf.createEntityManager();
+ OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
+ em.getTransaction().begin();
+
+ DogTable dog1 = new DogTable();
+ dog1.setName("helloDog1");
+ dog1.setDatastoreid(12);
+ dog1.setPrice(12000);
+
+ em.persist(dog1);
+ DogTable dog1a = new DogTable();
+ dog1a.setName("helloDog2");
+ dog1a.setDatastoreid(15);
+ dog1a.setPrice(22000);
+ em.persist(dog1a);
+ // add dog2
+ DogTable2 dog2 = new DogTable2();
+ dog2.setName("helloDog3");
+ dog2.setDatastoreid(12);
+ dog2.setPrice(15000);
+ em.persist(dog2);
+
+ DogTable2 dog2a = new DogTable2();
+ dog2a.setName("helloDog4");
+ dog2a.setDatastoreid(19);
+ dog2a.setPrice(25000);
+ em.persist(dog2a);
+ em.getTransaction().commit();
+
+ DogTable dog1x = em.find(DogTable.class, kem.getObjectId(dog1));
+ assertTrue(dog1x.getId2() == 20 || dog1x.getId2() == 21);
+ assertEquals(dog1x.getName(), "helloDog1");
+ dog1x.setName("Dog1");
+ dog1x.setDomestic(true);
+ DogTable dog11 = em.find(DogTable.class, kem.getObjectId(dog1a));
+ assertTrue(dog11.getId2() == 20 || dog11.getId2() == 21);
+ assertEquals(dog11.getName(), "helloDog2");
+ dog11.setName("Dog2");
+ dog11.setDomestic(true);
+ // update dog2
+ DogTable2 dog2x = em.find(DogTable2.class, kem.getObjectId(dog2));
+ assertTrue(dog2x.getId2() == 100 || dog2x.getId2() == 101);
+ assertEquals(dog2x.getName(), "helloDog3");
+ dog2x.setName("Dog3");
+ dog2x.setDomestic(true);
+ DogTable2 dog21 = em.find(DogTable2.class, kem.getObjectId(dog2a));
+ assertTrue(dog2x.getId2() == 100 || dog2x.getId2() == 101);
+ assertEquals(dog21.getName(), "helloDog4");
+ dog21.setName("Dog4");
+ dog21.setDomestic(true);
+
+ // get the update dog name
+
+ em.getTransaction().begin();
+ Query qry1 = em.createQuery("select d from DogTable d order by d.name");
+ List result1 = qry1.getResultList();
+ for (int index = 0; index < result1.size(); index++) {
+ DogTable dog4 = (DogTable) result1.get(index);
+ assertTrue(dog4.getId2() == 20 || dog4.getId2() == 21);
+ int j = index + 1;
+ assertEquals(dog4.getName(), "Dog" + j);
+
+ }
+
+ Query qry2 = em
+ .createQuery("select d from DogTable2 d order by d.name");
+ List result2 = qry2.getResultList();
+
+ for (int index = 0; index < result2.size(); index++) {
+ DogTable2 dog5 = (DogTable2) result2.get(index);
+ assertTrue(dog5.getId2() == 100 || dog5.getId2() == 101);
+ int j = index + 3;
+ assertEquals(dog5.getName(), "Dog" + j);
+ }
+
+ em.getTransaction().commit();
+ em.close();
+ }
+} // end of TestMultipleSchemaNames
diff --git a/openjpa-project/src/doc/manual/jpa_overview_meta.xml b/openjpa-project/src/doc/manual/jpa_overview_meta.xml
index e4f7e7c97..5d90a6f89 100644
--- a/openjpa-project/src/doc/manual/jpa_overview_meta.xml
+++ b/openjpa-project/src/doc/manual/jpa_overview_meta.xml
@@ -883,6 +883,19 @@ These string constants are defined in
org.apache.openjpa.persistence.Generator.
+
+If the entities are mapped to the same table name but with different schema
+name within one PersistenceUnit intentionally, and the
+strategy of GeneratedType.AUTO is used to generate the ID
+for each entity, a schema name for each entity must be explicitly declared
+either through the annotation or the mapping.xml file. Otherwise, the mapping
+tool only creates the tables for those entities with the schema names under
+each schema. In addition, there will be only one
+OPENJPA_SEQUENCE_TABLE created for all the entities within
+the PersistenceUnit if the entities are not identified
+with the schema name. Read and
+ in the Reference Guide.
+
diff --git a/openjpa-project/src/doc/manual/ref_guide_runtime.xml b/openjpa-project/src/doc/manual/ref_guide_runtime.xml
index cea92f5dc..8b87c4a02 100644
--- a/openjpa-project/src/doc/manual/ref_guide_runtime.xml
+++ b/openjpa-project/src/doc/manual/ref_guide_runtime.xml
@@ -1455,7 +1455,10 @@ This Seq has the following properties:
Table: The name of the sequence number table to use.
-Defaults to OPENJPA_SEQUENCE_TABLE.
+Defaults to OPENJPA_SEQUENCE_TABLE. If the entities are
+mapped to the same table name but with different schema name within one
+PersistenceUnit, one OPENJPA_SEQUENCE_TABLE is created
+for each schema.