use of org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.
the class ReplicatedTokenHolder method createCommands.
private byte[] createCommands(String tokenName) {
StorageEngine storageEngine = dependencies.resolveDependency(StorageEngine.class);
Collection<StorageCommand> commands = new ArrayList<>();
TransactionState txState = new TxState();
int tokenId = Math.toIntExact(idGeneratorFactory.get(tokenIdType).nextId());
createToken(txState, tokenName, tokenId);
try (StorageStatement statement = storageEngine.storeReadLayer().newStatement()) {
storageEngine.createCommands(commands, txState, statement, ResourceLocker.NONE, Long.MAX_VALUE);
} catch (CreateConstraintFailureException | TransactionFailureException | ConstraintValidationException e) {
throw new RuntimeException("Unable to create token '" + tokenName + "'", e);
}
return ReplicatedTokenRequestSerializer.commandBytes(commands);
}
use of org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.
the class KernelTransactionImplementation method commit.
private long commit() throws TransactionFailureException {
boolean success = false;
long txId = READ_ONLY;
try (CommitEvent commitEvent = transactionEvent.beginCommitEvent()) {
// Trigger transaction "before" hooks.
if (hasDataChanges()) {
try {
hooksState = hooks.beforeCommit(txState, this, storageEngine.storeReadLayer(), storageStatement);
if (hooksState != null && hooksState.failed()) {
TransactionHookException cause = hooksState.failure();
throw new TransactionFailureException(Status.Transaction.TransactionHookFailed, cause, "");
}
} finally {
beforeHookInvoked = true;
}
}
// Convert changes into commands and commit
if (hasChanges()) {
// grab all optimistic locks now, locks can't be deferred any further
statementLocks.prepareForCommit();
// use pessimistic locks for the rest of the commit process, locks can't be deferred any further
Locks.Client commitLocks = statementLocks.pessimistic();
// Gather up commands from the various sources
Collection<StorageCommand> extractedCommands = new ArrayList<>();
storageEngine.createCommands(extractedCommands, txState, storageStatement, commitLocks, lastTransactionIdWhenStarted);
if (hasLegacyIndexChanges()) {
legacyIndexTransactionState.extractCommands(extractedCommands);
}
/* Here's the deal: we track a quick-to-access hasChanges in transaction state which is true
* if there are any changes imposed by this transaction. Some changes made inside a transaction undo
* previously made changes in that same transaction, and so at some point a transaction may have
* changes and at another point, after more changes seemingly,
* the transaction may not have any changes.
* However, to track that "undoing" of the changes is a bit tedious, intrusive and hard to maintain
* and get right.... So to really make sure the transaction has changes we re-check by looking if we
* have produced any commands to add to the logical log.
*/
if (!extractedCommands.isEmpty()) {
// Finish up the whole transaction representation
PhysicalTransactionRepresentation transactionRepresentation = new PhysicalTransactionRepresentation(extractedCommands);
TransactionHeaderInformation headerInformation = headerInformationFactory.create();
long timeCommitted = clock.millis();
transactionRepresentation.setHeader(headerInformation.getAdditionalHeader(), headerInformation.getMasterId(), headerInformation.getAuthorId(), startTimeMillis, lastTransactionIdWhenStarted, timeCommitted, commitLocks.getLockSessionId());
// Commit the transaction
success = true;
TransactionToApply batch = new TransactionToApply(transactionRepresentation);
txId = transactionId = commitProcess.commit(batch, commitEvent, INTERNAL);
commitTime = timeCommitted;
}
}
success = true;
return txId;
} catch (ConstraintValidationException | CreateConstraintFailureException e) {
throw new ConstraintViolationTransactionFailureException(e.getUserMessage(new KeyReadTokenNameLookup(currentTransactionOperations.keyReadOperations())), e);
} finally {
if (!success) {
rollback();
} else {
afterCommit(txId);
}
}
}
use of org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.
the class PropertyConstraintsStressIT method createPropertyExistenceConstraintCommand.
private static WorkerCommand<Object, Boolean> createPropertyExistenceConstraintCommand(final GraphDatabaseService db, final String query) {
return new WorkerCommand<Object, Boolean>() {
@Override
public Boolean doWork(Object state) throws Exception {
boolean constraintCreationFailed = false;
try (Transaction tx = db.beginTx()) {
db.execute(query);
tx.success();
} catch (QueryExecutionException e) {
System.out.println("Constraint failed: " + e.getMessage());
if (Exceptions.rootCause(e) instanceof ConstraintValidationException) {
// Unable to create constraint since it is not consistent with existing data
constraintCreationFailed = true;
} else {
throw e;
}
}
if (!constraintCreationFailed) {
System.out.println("Constraint created: " + query);
}
return constraintCreationFailed;
}
};
}
use of org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.
the class UniquenessConstraintCreationIT method shouldAbortConstraintCreationWhenDuplicatesExist.
@Test
public void shouldAbortConstraintCreationWhenDuplicatesExist() throws Exception {
// given
Statement statement = statementInNewTransaction(AnonymousContext.writeToken());
// name is not unique for Foo in the existing data
int foo = statement.tokenWriteOperations().labelGetOrCreateForName("Foo");
int name = statement.tokenWriteOperations().propertyKeyGetOrCreateForName("name");
long node1 = statement.dataWriteOperations().nodeCreate();
statement.dataWriteOperations().nodeAddLabel(node1, foo);
statement.dataWriteOperations().nodeSetProperty(node1, Property.stringProperty(name, "foo"));
long node2 = statement.dataWriteOperations().nodeCreate();
statement.dataWriteOperations().nodeAddLabel(node2, foo);
statement.dataWriteOperations().nodeSetProperty(node2, Property.stringProperty(name, "foo"));
commit();
// when
LabelSchemaDescriptor descriptor = SchemaDescriptorFactory.forLabel(foo, name);
try {
SchemaWriteOperations schemaWriteOperations = schemaWriteOperationsInNewTransaction();
schemaWriteOperations.uniquePropertyConstraintCreate(descriptor);
fail("expected exception");
}// then
catch (CreateConstraintFailureException ex) {
assertEquals(ConstraintDescriptorFactory.uniqueForSchema(descriptor), ex.constraint());
Throwable cause = ex.getCause();
assertThat(cause, instanceOf(ConstraintValidationException.class));
String expectedMessage = String.format("Both Node(%d) and Node(%d) have the label `Foo` and property `name` = 'foo'", node1, node2);
String actualMessage = userMessage((ConstraintValidationException) cause);
assertEquals(expectedMessage, actualMessage);
}
}
Aggregations