use of org.eclipse.persistence.sequencing.DefaultSequence in project eclipselink by eclipse-ee4j.
the class SequencingManager method onConnectSequences.
/*
* If passed collection is null then connect all sequences used by owner session's descriptors.
* Otherwise connect sequences used by passed descriptors.
*/
protected void onConnectSequences(Collection<ClassDescriptor> descriptors) {
boolean isConnected = isConnected();
int nAlreadyConnectedSequences = 0;
if (connectedSequences == null) {
connectedSequences = new Vector<>();
} else {
nAlreadyConnectedSequences = connectedSequences.size();
}
boolean shouldUseTransaction = false;
boolean shouldUsePreallocation = false;
boolean shouldAcquireValueAfterInsert = false;
if (descriptors == null) {
descriptors = getOwnerSession().getDescriptors().values();
}
Iterator<ClassDescriptor> itDescriptors = descriptors.iterator();
while (itDescriptors.hasNext()) {
ClassDescriptor descriptor = itDescriptors.next();
// Find root sequence, because inheritance needs to be resolved here.
// TODO: The way we initialize sequencing needs to be in line with descriptor init.
ClassDescriptor parentDescriptor = descriptor;
while (!parentDescriptor.usesSequenceNumbers() && parentDescriptor.isChildDescriptor()) {
ClassDescriptor newDescriptor = getOwnerSession().getDescriptor(parentDescriptor.getInheritancePolicy().getParentClass());
// Avoid issue with error cases of self parent, or null parent.
if ((newDescriptor == null) || (newDescriptor == parentDescriptor)) {
break;
}
parentDescriptor = newDescriptor;
}
if (!parentDescriptor.usesSequenceNumbers()) {
continue;
}
String seqName = parentDescriptor.getSequenceNumberName();
Sequence sequence = getSequence(seqName);
if (sequence == null) {
sequence = new DefaultSequence(seqName);
getOwnerSession().getDatasourcePlatform().addSequence(sequence, isConnected);
}
// PERF: Initialize the sequence, this avoid having to look it up every time.
descriptor.setSequence(sequence);
if (connectedSequences.contains(sequence)) {
continue;
}
try {
if (sequence instanceof DefaultSequence && !connectedSequences.contains(getDefaultSequence())) {
getDefaultSequence().onConnect(getOwnerSession().getDatasourcePlatform());
connectedSequences.add(nAlreadyConnectedSequences, getDefaultSequence());
shouldUseTransaction |= getDefaultSequence().shouldUseTransaction();
shouldUsePreallocation |= getDefaultSequence().shouldUsePreallocation();
shouldAcquireValueAfterInsert |= getDefaultSequence().shouldAcquireValueAfterInsert();
}
sequence.onConnect(getOwnerSession().getDatasourcePlatform());
connectedSequences.addElement(sequence);
shouldUseTransaction |= sequence.shouldUseTransaction();
shouldUsePreallocation |= sequence.shouldUsePreallocation();
shouldAcquireValueAfterInsert |= sequence.shouldAcquireValueAfterInsert();
} catch (RuntimeException ex) {
// defaultSequence has to disconnect the last
for (int i = connectedSequences.size() - 1; i >= nAlreadyConnectedSequences; i--) {
try {
Sequence sequenceToDisconnect = connectedSequences.elementAt(i);
sequenceToDisconnect.onDisconnect(getOwnerSession().getDatasourcePlatform());
} catch (RuntimeException ex2) {
// ignore
}
}
if (nAlreadyConnectedSequences == 0) {
connectedSequences = null;
}
throw ex;
}
}
if (nAlreadyConnectedSequences == 0) {
if (shouldAcquireValueAfterInsert && !shouldUsePreallocation) {
whenShouldAcquireValueForAll = AFTER_INSERT;
} else if (!shouldAcquireValueAfterInsert && shouldUsePreallocation) {
whenShouldAcquireValueForAll = BEFORE_INSERT;
}
} else {
if (whenShouldAcquireValueForAll == AFTER_INSERT) {
if (!shouldAcquireValueAfterInsert || shouldUsePreallocation) {
whenShouldAcquireValueForAll = UNDEFINED;
}
} else if (whenShouldAcquireValueForAll == BEFORE_INSERT) {
if (shouldAcquireValueAfterInsert || !shouldUsePreallocation) {
whenShouldAcquireValueForAll = UNDEFINED;
}
}
}
atLeastOneSequenceShouldUseTransaction |= shouldUseTransaction;
atLeastOneSequenceShouldUsePreallocation |= shouldUsePreallocation;
}
use of org.eclipse.persistence.sequencing.DefaultSequence in project eclipselink by eclipse-ee4j.
the class SessionsFactory method buildSequence.
/**
* INTERNAL:
* Builds a Sequence from the given SequenceConfig.
*/
protected Sequence buildSequence(SequenceConfig sequenceConfig) {
if (sequenceConfig == null) {
return null;
}
String name = sequenceConfig.getName();
int size = sequenceConfig.getPreallocationSize();
if (sequenceConfig instanceof DefaultSequenceConfig) {
return new DefaultSequence(name, size);
} else if (sequenceConfig instanceof NativeSequenceConfig) {
return new NativeSequence(name, size);
} else if (sequenceConfig instanceof TableSequenceConfig) {
TableSequenceConfig tsc = (TableSequenceConfig) sequenceConfig;
return new TableSequence(name, size, tsc.getTable(), tsc.getNameField(), tsc.getCounterField());
} else if (sequenceConfig instanceof UnaryTableSequenceConfig) {
UnaryTableSequenceConfig utsc = (UnaryTableSequenceConfig) sequenceConfig;
return new UnaryTableSequence(name, size, utsc.getCounterField());
} else if (sequenceConfig instanceof XMLFileSequenceConfig) {
try {
// Can no longer reference class directly as in a different project.
@SuppressWarnings({ "unchecked" }) Class<Sequence> xmlClass = (Class<Sequence>) Class.forName("org.eclipse.persistence.eis.adapters.xmlfile.XMLFileSequence");
Sequence sequence = xmlClass.getConstructor().newInstance();
sequence.setName(name);
sequence.setInitialValue(size);
return sequence;
} catch (Exception missing) {
return null;
}
} else {
// Unknown SequenceConfig subclass - should never happen
return null;
}
}
use of org.eclipse.persistence.sequencing.DefaultSequence in project eclipselink by eclipse-ee4j.
the class DatasourcePlatform method setDefaultSequence.
/**
* Set default sequence. In case the passed sequence is of type DefaultSequence - use platformDefaultSequence
* with name and size of the passed sequence.
*/
@Override
public void setDefaultSequence(Sequence sequence) {
if (sequence instanceof DefaultSequence) {
Sequence platformDefaultSequence = createPlatformDefaultSequence();
if (platformDefaultSequence != null) {
platformDefaultSequence.setName(sequence.getName());
if (((DefaultSequence) sequence).hasPreallocationSize()) {
platformDefaultSequence.setPreallocationSize(sequence.getPreallocationSize());
}
}
defaultSequence = platformDefaultSequence;
} else {
defaultSequence = sequence;
}
}
use of org.eclipse.persistence.sequencing.DefaultSequence in project eclipselink by eclipse-ee4j.
the class OracleNativeSeqInitTest method setup.
@Override
public void setup() {
if (!getSession().getPlatform().supportsSequenceObjects()) {
throw new TestWarningException("This test requires a platform that supports sequence objects");
}
ClassDescriptor descriptor = getSession().getDescriptor(Employee.class);
if (!descriptor.usesSequenceNumbers()) {
throw new TestWarningException("Employee doesn't use sequencing");
}
originalSequence = getSession().getPlatform().getSequence(descriptor.getSequenceNumberName());
usesNativeSequencingOriginal = (originalSequence instanceof NativeSequence || (originalSequence instanceof DefaultSequence && getSession().getPlatform().getDefaultSequence() instanceof NativeSequence)) && !originalSequence.shouldAcquireValueAfterInsert();
if (!usesNativeSequencingOriginal) {
NativeSequence newSequence = new NativeSequence(originalSequence.getName(), originalSequence.getPreallocationSize());
newSequence.onConnect(originalSequence.getDatasourcePlatform());
getAbstractSession().getPlatform().addSequence(newSequence);
sequence = newSequence;
} else {
sequence = originalSequence;
}
seqPreallocationSizeOriginal = originalSequence.getPreallocationSize();
lastSeqNumberOriginal = getSession().getNextSequenceNumberValue(Employee.class).intValue() - 1;
usesBatchWritingOriginal = getSession().getPlatform().usesBatchWriting();
shouldCacheAllStatementsOriginal = getSession().getPlatform().shouldCacheAllStatements();
getDatabaseSession().getSequencingControl().initializePreallocated();
sequenceDefinition = new SequenceObjectDefinition(sequence);
sequenceDefinition.setQualifier(getSession().getLogin().getTableQualifier());
if (shouldUseSchemaManager) {
schemaManager = new SchemaManager(getDatabaseSession());
// make sure that upcoming DROP and CREATE haven't been cached
// and therefore for sure will go through
getSession().getPlatform().setShouldCacheAllStatements(false);
// This is the worst case scenario settings - SchemaManager should handle it.
getSession().getPlatform().setUsesBatchWriting(true);
getSession().getPlatform().setShouldCacheAllStatements(true);
} else {
getSession().getPlatform().setUsesBatchWriting(false);
getSession().getPlatform().setShouldCacheAllStatements(false);
}
// all three modes start with dropping an existing sequence (if any)
try {
drop();
} catch (DatabaseException exception) {
// Ignore already deleted
}
if (mode == DROP_CREATE) {
// sequence doesn't exist.
// create sequence with seqPreallocationSize.
// note that both increment and starting value are set to
// sequenceDefinition.getIncrement()
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSize);
create();
// next available sequence number.
idExpected = 1;
} else if (mode == CREATE_CREATE) {
// sequence doesn't exist,
// create sequence with seqPreallocationSizeOld
// note that both increment and starting value are set to
// sequenceDefinition.getIncrement()
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSizeOld);
create();
// now sequence exists,
// create sequence with seqPreallocationSize
// Note that createOnDatabase will call alterOnDatabase
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSize);
create();
// next available sequence number.
// note that the second createOnDatabase selects NEXTVAL during existance check,
// because it is the first call to NEXTVAL, the starting sequence value is returned,
// and this value was set to seqPreallocationSizeOld by the first createOnDatabase
idExpected = 1 + seqPreallocationSizeOld;
} else if (mode == NEXTVAL_ALTER) {
// sequence doesn't exist,
// create sequence with seqPreallocationSizeOld
// note that both increment and starting value are set to
// sequenceDefinition.getIncrement()
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSizeOld);
create();
// now sequence exists,
// select NEXTVAL
// because it is the first call to NEXTVAL, the starting sequence value is returned,
// and this value was set to seqPreallocationSizeOld by the first createOnDatabase
sequenceDefinition.checkIfExist((AbstractSession) getSession());
// alter increment of sequence with seqPreallocationSize.
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSize);
alter();
// next available sequence number.
// because there was just one call to NEXTVAL, the starting sequence value is returned,
// and this value was set to seqPreallocationSizeOld by createOnDatabase
idExpected = 1 + seqPreallocationSizeOld;
} else if (mode == CREATE_ALTER) {
// sequence doesn't exist,
// create sequence with seqPreallocationSizeOld
// note that both increment and starting value are set to
// sequenceDefinition.getIncrement()
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSizeOld);
create();
// alter increment of sequence with seqPreallocationSize.
sequence.setInitialValue(1);
sequence.setPreallocationSize(seqPreallocationSize);
alter();
// next available sequence number.
idExpected = 1;
}
getSession().getPlatform().getSequence(descriptor.getSequenceNumberName()).setPreallocationSize(seqPreallocationSize);
}
use of org.eclipse.persistence.sequencing.DefaultSequence in project eclipselink by eclipse-ee4j.
the class DefaultTableGenerator method initTableSchema.
/**
* Build tables/fields information into the table creator object from a EclipseLink descriptor.
* This should handle most of the direct/relational mappings except many-to-many and direct
* collection/map mappings, which must be down in postInit method.
*/
protected void initTableSchema(ClassDescriptor descriptor) {
TableDefinition tableDefintion = null;
if (descriptor.hasTablePerClassPolicy() && descriptor.isAbstract()) {
return;
}
// create a table definition for each mapped database table
for (DatabaseTable table : descriptor.getTables()) {
tableDefintion = getTableDefFromDBTable(table);
}
// build each field definition and figure out which table it goes
for (DatabaseField dbField : descriptor.getFields()) {
if (dbField.isCreatable()) {
boolean isPKField = false;
// first check if the field is a pk field in the default table.
isPKField = descriptor.getPrimaryKeyFields().contains(dbField);
// then check if the field is a pk field in the secondary table(s), this is only applied to the multiple tables case.
Map<DatabaseField, DatabaseField> secondaryKeyMap = descriptor.getAdditionalTablePrimaryKeyFields().get(dbField.getTable());
if (secondaryKeyMap != null) {
isPKField = isPKField || secondaryKeyMap.containsValue(dbField);
}
// Now check if it is a tenant discriminat column primary key field.
isPKField = isPKField || dbField.isPrimaryKey();
// build or retrieve the field definition.
FieldDefinition fieldDef = getFieldDefFromDBField(dbField);
if (isPKField) {
fieldDef.setIsPrimaryKey(true);
// Check if the generation strategy is IDENTITY
String sequenceName = descriptor.getSequenceNumberName();
DatabaseLogin login = this.project.getLogin();
Sequence seq = login.getSequence(sequenceName);
if (seq instanceof DefaultSequence) {
seq = login.getDefaultSequence();
}
// The native sequence whose value should be acquired after insert is identity sequence
boolean isIdentity = seq instanceof NativeSequence && seq.shouldAcquireValueAfterInsert();
fieldDef.setIsIdentity(isIdentity);
}
// find the table the field belongs to, and add it to the table, only if not already added.
tableDefintion = this.tableMap.get(dbField.getTableName());
if ((tableDefintion != null) && !tableDefintion.getFields().contains(fieldDef)) {
tableDefintion.addField(fieldDef);
}
}
}
}
Aggregations