mirror of https://github.com/apache/openjpa.git
OPENJPA-803 Added support to allow a specific schema name to be specified on sequence generators per JPA 2.0.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@728147 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
16b7b1a7f7
commit
c924cc2fc8
|
@ -81,6 +81,8 @@ public class NativeJDBCSeq
|
|||
private String _tableName = "DUAL";
|
||||
private boolean _subTable = false;
|
||||
|
||||
private String _schema = null;
|
||||
|
||||
/**
|
||||
* The sequence name. Defaults to <code>OPENJPA_SEQUENCE</code>.
|
||||
*/
|
||||
|
@ -169,9 +171,12 @@ public class NativeJDBCSeq
|
|||
if (group.isKnownSequence(_seqName))
|
||||
return;
|
||||
|
||||
String schemaName = Strings.getPackageName(_seqName);
|
||||
if (schemaName.length() == 0)
|
||||
schemaName = Schemas.getNewTableSchema(_conf);
|
||||
String schemaName = getSchema();
|
||||
if (schemaName == null || schemaName.length() == 0) {
|
||||
schemaName = Strings.getPackageName(_seqName);
|
||||
if (schemaName.length() == 0)
|
||||
schemaName = Schemas.getNewTableSchema(_conf);
|
||||
}
|
||||
|
||||
// create table in this group
|
||||
Schema schema = group.getSchema(schemaName);
|
||||
|
@ -228,9 +233,17 @@ public class NativeJDBCSeq
|
|||
*/
|
||||
private void buildSequence() {
|
||||
String seqName = Strings.getClassName(_seqName);
|
||||
String schemaName = Strings.getPackageName(_seqName);
|
||||
if (schemaName.length() == 0)
|
||||
schemaName = Schemas.getNewTableSchema(_conf);
|
||||
// JPA 2 added schema as a configurable attribute on
|
||||
// sequence generator. OpenJPA <= 1.x allowed this via
|
||||
// schema.sequence on the sequence name. Specifying a schema
|
||||
// name on the annotation or in the orm will override the old
|
||||
// behavior.
|
||||
String schemaName = _schema;
|
||||
if (schemaName == null || schemaName.length() == 0) {
|
||||
schemaName = Strings.getPackageName(_seqName);
|
||||
if (schemaName.length() == 0)
|
||||
schemaName = Schemas.getNewTableSchema(_conf);
|
||||
}
|
||||
|
||||
// build the sequence in one of the designated schemas
|
||||
SchemaGroup group = new SchemaGroup();
|
||||
|
@ -380,4 +393,12 @@ public class NativeJDBCSeq
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSchema(String _schema) {
|
||||
this._schema = _schema;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
return _schema;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ public class SequenceMetaData
|
|||
private static final String PROP_INITIAL_VALUE = "InitialValue";
|
||||
private static final String PROP_ALLOCATE = "Allocate";
|
||||
private static final String PROP_INCREMENT = "Increment";
|
||||
private static final String PROP_SCHEMA = "Schema";
|
||||
private static final String PROP_CATALOG = "Catalog";
|
||||
|
||||
private static final Localizer _loc = Localizer.forPackage
|
||||
(SequenceMetaData.class);
|
||||
|
@ -87,6 +89,8 @@ public class SequenceMetaData
|
|||
private int _increment = -1;
|
||||
private int _allocate = -1;
|
||||
private int _initial = -1;
|
||||
private String _schema = null;
|
||||
private String _catalog = null;
|
||||
|
||||
// instantiated lazily
|
||||
private transient Seq _instance = null;
|
||||
|
@ -306,6 +310,28 @@ public class SequenceMetaData
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set/Get the schema name
|
||||
*/
|
||||
public void setSchema(String schema) {
|
||||
this._schema = schema;
|
||||
}
|
||||
|
||||
public String getSchema() {
|
||||
return _schema;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set/Get the catalog name
|
||||
*/
|
||||
public void setCatalog(String catalog) {
|
||||
this._catalog = catalog;
|
||||
}
|
||||
|
||||
public String getCatalog() {
|
||||
return _catalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new plugin value for sequences. Returns a standard
|
||||
* {@link SeqValue} by default.
|
||||
|
@ -322,6 +348,8 @@ public class SequenceMetaData
|
|||
appendProperty(props, PROP_INITIAL_VALUE, _initial);
|
||||
appendProperty(props, PROP_ALLOCATE, _allocate);
|
||||
appendProperty(props, PROP_INCREMENT, _increment);
|
||||
appendProperty(props, PROP_SCHEMA, _schema);
|
||||
appendProperty(props, PROP_CATALOG, _catalog);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
// This entity is defined via sequence-orm.xml
|
||||
public class NativeORMSequenceEntity {
|
||||
|
||||
public static final String SCHEMA_NAME = "ORMSCHEMA";
|
||||
public static final String SEQ_NAME = "ORMSEQ";
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import static javax.persistence.GenerationType.SEQUENCE;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
|
||||
@Entity
|
||||
@Table(name="NativeSeqEnt")
|
||||
public class NativeSequenceEntity {
|
||||
|
||||
public static final String SEQ_NAME = "SCHEMASEQ";
|
||||
public static final String SCHEMA_NAME = "SEQSCHEMA";
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name="seq_with_schema", sequenceName=SEQ_NAME,
|
||||
schema=SCHEMA_NAME, initialValue=10)
|
||||
@GeneratedValue(strategy=SEQUENCE, generator="seq_with_schema")
|
||||
private int id;
|
||||
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.schema.Sequence;
|
||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
|
||||
import org.apache.openjpa.persistence.test.AllowFailure;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
/**
|
||||
* Test for sequence generator. Some databases currently (Derby) do not support
|
||||
* native sequences so this method is allowed to fail until such time when the
|
||||
* test corpus can support database or dictionary support specific
|
||||
* configuration.
|
||||
*
|
||||
* @author Jeremy Bauer
|
||||
*/
|
||||
@AllowFailure(true)
|
||||
public class TestSequenceGenerator extends SingleEMFTestCase {
|
||||
|
||||
public void setUp()
|
||||
throws Exception {
|
||||
setUp(NativeSequenceEntity.class,
|
||||
NativeORMSequenceEntity.class,
|
||||
CLEAR_TABLES);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPersistenceUnitName() {
|
||||
return "native-seq-pu";
|
||||
}
|
||||
|
||||
/*
|
||||
* Test use of the schema attribute on a native sequence generator. Some
|
||||
* databases do not support native sequences so this method is
|
||||
* currently allowed to fail.
|
||||
*/
|
||||
public void testSequenceSchema() {
|
||||
OpenJPAEntityManagerSPI em = emf.createEntityManager();
|
||||
NativeSequenceEntity nse = new NativeSequenceEntity();
|
||||
nse.setName("Test");
|
||||
em.getTransaction().begin();
|
||||
em.persist(nse);
|
||||
em.getTransaction().commit();
|
||||
em.refresh(nse);
|
||||
// Validate the id is >= the initial value
|
||||
// Assert the sequence was created in the DB
|
||||
assertTrue(sequenceExists(em, NativeSequenceEntity.SCHEMA_NAME,
|
||||
NativeSequenceEntity.SEQ_NAME));
|
||||
// Assert the id is >= the initial value
|
||||
assertTrue(nse.getId() >= 10);
|
||||
em.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test use of the schema element on a native sequence generator. Some
|
||||
* databases do not support native sequences so this method is
|
||||
* currently allowed to fail.
|
||||
*/
|
||||
public void testORMSequenceSchema() {
|
||||
OpenJPAEntityManagerSPI em = emf.createEntityManager();
|
||||
NativeORMSequenceEntity nse = new NativeORMSequenceEntity();
|
||||
nse.setName("TestORM");
|
||||
em.getTransaction().begin();
|
||||
em.persist(nse);
|
||||
em.getTransaction().commit();
|
||||
em.refresh(nse);
|
||||
// Assert the sequence was created in the DB
|
||||
assertTrue(sequenceExists(em, NativeORMSequenceEntity.SCHEMA_NAME,
|
||||
NativeORMSequenceEntity.SEQ_NAME));
|
||||
// Assert the id is >= the initial value
|
||||
assertTrue(nse.getId() >= 2000);
|
||||
em.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to verify a sequence was created for the given schema and
|
||||
* sequence name.
|
||||
*/
|
||||
private boolean sequenceExists(OpenJPAEntityManagerSPI em, String schema,
|
||||
String sequence) {
|
||||
JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
|
||||
DBDictionary dict = conf.getDBDictionaryInstance();
|
||||
Connection conn = (Connection)em.getConnection();
|
||||
try {
|
||||
DatabaseMetaData dbmd = conn.getMetaData();
|
||||
Sequence[] seqs = dict.getSequences(dbmd, null, schema,
|
||||
sequence, conn);
|
||||
if (seqs != null && seqs.length == 1 &&
|
||||
seqs[0].getName().equalsIgnoreCase(sequence) &&
|
||||
seqs[0].getSchemaName().equalsIgnoreCase(schema))
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -113,4 +113,14 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="native-seq-pu">
|
||||
<mapping-file>org/apache/openjpa/persistence/sequence/sequence-orm.xml</mapping-file>
|
||||
<class>org.apache.openjpa.persistence.jdbc.annotations.NativeSequenceEntity</class>
|
||||
<class>org.apache.openjpa.persistence.jdbc.annotations.NativeORMSequenceEntity</class>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<entity name="NativeORMSequenceEntity"
|
||||
class="org.apache.openjpa.persistence.jdbc.annotations.NativeORMSequenceEntity"
|
||||
access="FIELD">
|
||||
<table name="NativeOrmSeqEnt"/>
|
||||
|
||||
<sequence-generator name="ormseq_with_schema"
|
||||
sequence-name="ORMSEQ"
|
||||
schema="ORMSCHEMA"
|
||||
initial-value="2000"/>
|
||||
<attributes>
|
||||
<id name="id">
|
||||
<generated-value strategy="SEQUENCE"
|
||||
generator="ormseq_with_schema"/>
|
||||
</id>
|
||||
|
||||
<basic name="name"/>
|
||||
</attributes>
|
||||
</entity>
|
||||
</entity-mappings>
|
|
@ -1570,6 +1570,8 @@ public class AnnotationPersistenceMetaDataParser
|
|||
String seq = gen.sequenceName();
|
||||
int initial = gen.initialValue();
|
||||
int allocate = gen.allocationSize();
|
||||
String schema = gen.schema();
|
||||
String catalog = gen.catalog();
|
||||
// don't allow initial of 0 b/c looks like def value
|
||||
if (initial == 0)
|
||||
initial = 1;
|
||||
|
@ -1593,6 +1595,8 @@ public class AnnotationPersistenceMetaDataParser
|
|||
meta.setSequence(seq);
|
||||
meta.setInitialValue(initial);
|
||||
meta.setAllocate(allocate);
|
||||
meta.setSchema(schema);
|
||||
meta.setCatalog(catalog);
|
||||
meta.setSource(getSourceFile(), (el instanceof Class) ? el : null,
|
||||
meta.SRC_ANNOTATIONS);
|
||||
}
|
||||
|
|
|
@ -696,6 +696,10 @@ public class AnnotationPersistenceMetaDataSerializer
|
|||
ab.add("initialValue", meta.getInitialValue());
|
||||
if (meta.getAllocate() != 50 && meta.getAllocate() != -1)
|
||||
ab.add("allocationSize", meta.getAllocate());
|
||||
if (meta.getSchema() != null)
|
||||
ab.add("schema", meta.getSchema());
|
||||
if (meta.getCatalog() != null)
|
||||
ab.add("catalog", meta.getCatalog());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -958,6 +958,8 @@ public class XMLPersistenceMetaDataParser
|
|||
int initial = val == null ? 1 : Integer.parseInt(val);
|
||||
val = attrs.getValue("allocation-size");
|
||||
int allocate = val == null ? 50 : Integer.parseInt(val);
|
||||
String schema = attrs.getValue("schema");
|
||||
String catalog = attrs.getValue("catalog");
|
||||
|
||||
String clsName, props;
|
||||
if (seq == null || seq.indexOf('(') == -1) {
|
||||
|
@ -973,6 +975,8 @@ public class XMLPersistenceMetaDataParser
|
|||
meta.setSequence(seq);
|
||||
meta.setInitialValue(initial);
|
||||
meta.setAllocate(allocate);
|
||||
meta.setSchema(schema);
|
||||
meta.setCatalog(catalog);
|
||||
|
||||
Object cur = currentElement();
|
||||
Object scope = (cur instanceof ClassMetaData)
|
||||
|
|
Loading…
Reference in New Issue