blob: e1b768966c2003b1a9d0f99da35e8a8345c63f1f [file] [log] [blame]
/*
* Copyright (c) 2018, 2021 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
*/
package org.eclipse.persistence.testing.tests.feature;
import org.eclipse.persistence.descriptors.*;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.sequencing.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.sequencing.*;
/**
* The purpose of this test is to test that when Sequencing shouldAcquireValueAfterInsert is set,
* the SQL which is generated for an insert query does not include column name and values for the
* sequence number column defined for the object being inserted.
*/
public class SequenceFieldRemovalForAcquireValueAfterInsertTest extends TestCase {
protected ClassDescriptor descriptor;
protected SQLStringListener sqlListener;
protected ModifyRowModifier modifyRowModifier;
protected Sequence oldSequence;
protected String sqlString;
public SequenceFieldRemovalForAcquireValueAfterInsertTest() {
super();
setDescription("Tests removing the sequence field from an SQL insert statement, when Sequencing shouldAcquireValueAfterInsert is true");
}
@Override
public void setup() {
this.descriptor = getSession().getDescriptor(SeqTestClass1.class);
String sequenceNumberName = descriptor.getSequenceNumberName();
Sequence sequence = getSession().getLogin().getSequence(sequenceNumberName);
DatabasePlatform platform = getDatabaseSession().getPlatform();
if (!platform.supportsNativeSequenceNumbers() || !platform.supportsIdentity()) {
throw new TestWarningException("Test only supported on platforms supporting sequencing and identity");
}
// if the sequence is not native, change it to be native and cache the old sequence
if (!sequence.isNative()) {
this.oldSequence = sequence;
NativeSequence newSequence = new NativeSequence(sequenceNumberName, 1);
newSequence.setShouldAcquireValueAfterInsert(true);
getDatabaseSession().getLogin().removeSequence(sequenceNumberName);
getDatabaseSession().getLogin().addSequence(newSequence);
getDatabaseSession().getSequencingControl().resetSequencing();
}
this.sqlListener = new SQLStringListener();
this.descriptor.getEventManager().addListener(sqlListener);
// need to modify the size of the row to force reprepare
this.modifyRowModifier = new ModifyRowModifier();
this.descriptor.getEventManager().addListener(modifyRowModifier);
beginTransaction();
}
@Override
public void test() {
UnitOfWork uow = getDatabaseSession().acquireUnitOfWork();
SeqTestClass1 object = new SeqTestClass1();
object.setTest1("aTestValue");
object.setTest2(ModifyRowModifier.OMISSION_MARKER); // marker to have modify row altered
uow.registerObject(object);
try {
uow.commit();
sqlString = this.sqlListener.getSQLString();
} catch (DatabaseException d) {
// catch exception, don't rethrow - only need SQL generated
sqlString = ((DatabaseCall)d.getCall()).getSQLString();
}
if (sqlString == null) {
throw new TestErrorException("Generated SQL string is null");
}
}
@Override
public void reset() {
rollbackTransaction();
if (sqlListener != null) {
this.descriptor.getEventManager().removeListener(sqlListener);
}
if (modifyRowModifier != null) {
this.descriptor.getEventManager().removeListener(modifyRowModifier);
}
// if sequencing was changed, reset to the previous sequence
if (oldSequence != null) {
getDatabaseSession().getLogin().removeSequence(descriptor.getSequenceNumberName());
getDatabaseSession().getLogin().addSequence(oldSequence);
this.oldSequence = null;
getDatabaseSession().getSequencingControl().resetSequencing();
}
}
@Override
public void verify() {
String fieldName = descriptor.getSequenceNumberField().getName();
String qualifiedFieldName = descriptor.getSequenceNumberField().getQualifiedName();
if (sqlString.indexOf(qualifiedFieldName) != -1 || sqlString.indexOf(fieldName) != -1) {
throw new TestErrorException("Invalid SQL String - sequence field " + fieldName + " was included in SQL: (" + sqlString + ")"
+ "- incorrect for shouldAcquireValueAfterInsert = true");
}
}
class SQLStringListener extends DescriptorEventAdapter {
protected String sqlString;
@Override
public void postInsert(DescriptorEvent event) {
sqlString = event.getQuery().getSQLString();
}
public String getSQLString() {
return this.sqlString;
}
}
class ModifyRowModifier extends DescriptorEventAdapter {
public static final String OMISSION_MARKER = "omit_this_field";
@Override
public void aboutToInsert(DescriptorEvent event) {
DataRecord modifyRow = event.getRecord();
Object[] keys = modifyRow.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
Object key = keys[i];
Object value = modifyRow.get(key);
if (value != null && value.equals(OMISSION_MARKER)) {
modifyRow.remove(key);
}
}
}
}
}