org.eclipse.persistence.tools.schemaframework.SequenceObjectDefinition Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// 07/25/2008-1.0 Michael OBrien
// - 242120: Let the DB exception in alterOnDatabase() propagate so as not to
// cause an infinite loop when ddl generation updates fail on a JTA DS
// 09/14/2011-2.3.1 Guy Pelletier
// - 357533: Allow DDL queries to execute even when Multitenant entities are part of the PU
package org.eclipse.persistence.tools.schemaframework;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.sequencing.Sequence;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
/**
*
* Purpose: Sequence definition Native Sequence object.
*
*/
public class SequenceObjectDefinition extends SequenceDefinition {
/**
* INTERNAL:
* Should be a sequence defining sequence object in the db:
* either NativeSequence with shouldAcquireValueAfterInsert() returning false;
* or DefaultSequence (only if case platform.getDefaultSequence() is a
* NativeSequence with shouldAcquireValueAfterInsert() returning false).
*/
public SequenceObjectDefinition(Sequence sequence) {
super(sequence);
}
/**
* INTERNAL:
* Return the SQL required to create the Oracle sequence object.
*/
@Override
public Writer buildCreationWriter(AbstractSession session, Writer writer) {
try {
// startWith value calculated using the initial value and increment.
// The first time TopLink calls select nextval, the value equal to startWith is returned.
// The first sequence value EclipseLink may assign is startWith - getIncrement() + 1.
int startWith = sequence.getInitialValue() + sequence.getPreallocationSize() - 1;
session.getPlatform().buildSequenceObjectCreationWriter(writer, getFullName(), sequence.getPreallocationSize(), startWith);
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Return the SQL required to drop the Oracle sequence object.
*/
@Override
public Writer buildDeletionWriter(AbstractSession session, Writer writer) {
try {
session.getPlatform().buildSequenceObjectDeletionWriter(writer, getFullName());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Return the SQL required to alter INCREMENT BY
*/
public Writer buildAlterIncrementWriter(AbstractSession session, Writer writer) {
try {
session.getPlatform().buildSequenceObjectAlterIncrementWriter(writer, getFullName(), sequence.getPreallocationSize());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Check if the sequence object already exists, in which case don't create it.
*/
@Override
public boolean checkIfExist(AbstractSession session) throws DatabaseException {
boolean isConnected = sequence.isConnected();
// temporary connect sequence if it's not connected.
if(!isConnected) {
sequence.onConnect(session.getPlatform());
}
try {
if(sequence.shouldUsePreallocation()) {
sequence.getGeneratedVector(null, session);
} else {
sequence.getGeneratedValue(null, session);
}
return true;
} catch (DatabaseException databaseException) {
return false;
} catch (ValidationException validationException) {
// This exception indicates that the current preallocationSize
// is greater than the returned value.
// It should be ignored because sequence actually exists in the db.
if(validationException.getErrorCode() == ValidationException.SEQUENCE_SETUP_INCORRECTLY) {
return true;
} else {
throw validationException;
}
} finally {
if(!isConnected) {
sequence.onDisconnect(session.getPlatform());
}
}
}
/**
* INTERNAL:
* Indicates whether alterIncrement is supported
*/
@Override
public boolean isAlterSupported(AbstractSession session) {
return session.getPlatform().isAlterSequenceObjectSupported();
}
/**
* INTERNAL:
* Execute the SQL required to alter sequence increment.
* Assume that the sequence exists.
*/
@Override
public void alterOnDatabase(AbstractSession session) throws EclipseLinkException {
// Bug# 242120: Let the DatabaseException propagate and do not call
// createOnDatabase(session) which would cause an infinite loop on a JTA connection
session.priviledgedExecuteNonSelectingCall(new SQLCall(buildAlterIncrementWriter(session, new StringWriter()).toString()));
}
/**
* INTERNAL:
* Execute the SQL required to alter sequence increment.
* Assume that the sequence exists.
*/
public void alterIncrement(AbstractSession session, Writer schemaWriter) throws ValidationException {
if (schemaWriter == null) {
this.alterOnDatabase(session);
} else {
this.buildAlterIncrementWriter(session, schemaWriter);
}
}
/**
* INTERNAL:
* Most major databases support a creator name scope.
* This means whenever the database object is referenced, it must be qualified.
*/
@Override
public String getFullName() {
return sequence.getQualified(getName());
}
}