Search in sources :

Example 6 with UniquePropertyValueValidationException

use of org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException in project neo4j by neo4j.

the class UniquenessConstraintValidationIT method shouldEnforceOnSetProperty.

@Test
void shouldEnforceOnSetProperty() throws Exception {
    // given
    constrainedNode("Label1", "key1", "value1");
    KernelTransaction transaction = newTransaction(AnonymousContext.writeToken());
    // when
    long node = createLabeledNode(transaction, "Label1");
    try {
        int propertyKeyId = transaction.tokenWrite().propertyKeyGetOrCreateForName("key1");
        transaction.dataWrite().nodeSetProperty(node, propertyKeyId, Values.of("value1"));
        fail("should have thrown exception");
    }// then
     catch (UniquePropertyValueValidationException e) {
        assertThat(e.getUserMessage(transaction.tokenRead())).contains("`key1` = 'value1'");
    }
    commit();
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) Test(org.junit.jupiter.api.Test)

Example 7 with UniquePropertyValueValidationException

use of org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException in project neo4j by neo4j.

the class ConstraintIndexCreatorTest method shouldDropIndexIfPopulationFails.

@Test
void shouldDropIndexIfPopulationFails() throws Exception {
    // given
    IndexingService indexingService = mock(IndexingService.class);
    IndexProxy indexProxy = mock(IndexProxy.class);
    when(indexingService.getIndexProxy(index)).thenReturn(indexProxy);
    when(indexProxy.getDescriptor()).thenReturn(index);
    when(schemaRead.indexGetForName(constraint.getName())).thenReturn(IndexDescriptor.NO_INDEX, index);
    IndexEntryConflictException cause = new IndexEntryConflictException(2, 1, Values.of("a"));
    doThrow(new IndexPopulationFailedKernelException("some index", cause)).when(indexProxy).awaitStoreScanCompleted(anyLong(), any());
    when(schemaRead.index(any(SchemaDescriptor.class))).thenReturn(// first claim it doesn't exist, because it doesn't... so
    Iterators.emptyResourceIterator()).thenReturn(// then after it failed claim it does exist
    Iterators.iterator(index));
    ConstraintIndexCreator creator = new ConstraintIndexCreator(() -> kernel, indexingService, logProvider);
    // when
    KernelTransactionImplementation transaction = createTransaction();
    UniquePropertyValueValidationException exception = assertThrows(UniquePropertyValueValidationException.class, () -> creator.createUniquenessConstraintIndex(transaction, constraint, prototype));
    assertEquals("Existing data does not satisfy Constraint( name='constraint', type='UNIQUENESS', schema=(:Label {prop}) ): " + "Both node 2 and node 1 share the property value ( String(\"a\") )", exception.getMessage());
    assertEquals(2, kernel.transactions.size());
    KernelTransactionImplementation tx1 = kernel.transactions.get(0);
    verify(tx1).indexUniqueCreate(prototype);
    verify(schemaRead, times(2)).indexGetForName(constraint.getName());
    verifyNoMoreInteractions(schemaRead);
    KernelTransactionImplementation kti2 = kernel.transactions.get(1);
    verify(kti2).addIndexDoDropToTxState(index);
}
Also used : ConstraintIndexCreator(org.neo4j.kernel.impl.api.state.ConstraintIndexCreator) UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) IndexingService(org.neo4j.kernel.impl.api.index.IndexingService) IndexPopulationFailedKernelException(org.neo4j.kernel.api.exceptions.index.IndexPopulationFailedKernelException) KernelTransactionImplementation(org.neo4j.kernel.impl.api.KernelTransactionImplementation) IndexProxy(org.neo4j.kernel.impl.api.index.IndexProxy) IndexEntryConflictException(org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException) Test(org.junit.jupiter.api.Test)

Example 8 with UniquePropertyValueValidationException

use of org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException in project neo4j by neo4j.

the class StateHandlingStatementOperations method uniquePropertyConstraintCreate.

@Override
public UniquenessConstraintDescriptor uniquePropertyConstraintCreate(KernelStatement state, LabelSchemaDescriptor descriptor) throws CreateConstraintFailureException {
    UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema(descriptor);
    try {
        if (state.hasTxStateWithChanges() && // ..., DROP, *CREATE*
        state.txState().indexDoUnRemove(constraint.ownedIndexDescriptor())) {
            // creation is undoing a drop
            if (// CREATE, ..., DROP, *CREATE*
            !state.txState().constraintDoUnRemove(constraint)) {
                // ... the drop we are undoing did itself undo a prior create...
                state.txState().constraintDoAdd(constraint, state.txState().indexCreatedForConstraint(constraint));
            }
        } else // *CREATE*
        {
            // create from scratch
            Iterator<ConstraintDescriptor> it = storeLayer.constraintsGetForSchema(descriptor);
            while (it.hasNext()) {
                if (it.next().equals(constraint)) {
                    return constraint;
                }
            }
            long indexId = constraintIndexCreator.createUniquenessConstraintIndex(state, this, descriptor);
            state.txState().constraintDoAdd(constraint, indexId);
        }
        return constraint;
    } catch (UniquePropertyValueValidationException | DropIndexFailureException | TransactionFailureException e) {
        throw new CreateConstraintFailureException(constraint, e);
    }
}
Also used : UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) TransactionFailureException(org.neo4j.kernel.api.exceptions.TransactionFailureException) ConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptor) UniquenessConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.UniquenessConstraintDescriptor) NodeExistenceConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.NodeExistenceConstraintDescriptor) RelExistenceConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.RelExistenceConstraintDescriptor) UniquenessConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.UniquenessConstraintDescriptor) DropIndexFailureException(org.neo4j.kernel.api.exceptions.schema.DropIndexFailureException) CreateConstraintFailureException(org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException)

Example 9 with UniquePropertyValueValidationException

use of org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException in project neo4j by neo4j.

the class ConstraintIndexCreator method createUniquenessConstraintIndex.

/**
     * You MUST hold a schema write lock before you call this method.
     * However the schema write lock is temporarily released while populating the index backing the constraint.
     * It goes a little like this:
     * <ol>
     * <li>Prerequisite: Getting here means that there's an open schema transaction which has acquired the
     * SCHEMA WRITE lock.</li>
     * <li>Index schema rule which is backing the constraint is created in a nested mini-transaction
     * which doesn't acquire any locking, merely adds tx state and commits so that the index rule is applied
     * to the store, which triggers the index population</li>
     * <li>Release the SCHEMA WRITE lock</li>
     * <li>Await index population to complete</li>
     * <li>Acquire the SCHEMA WRITE lock (effectively blocking concurrent transactions changing
     * data related to this constraint, and it so happens, most other transactions as well) and verify
     * the uniqueness of the built index</li>
     * <li>Leave this method, knowing that the uniqueness constraint rule will be added to tx state
     * and this tx committed, which will create the uniqueness constraint</li>
     * </ol>
     */
public long createUniquenessConstraintIndex(KernelStatement state, SchemaReadOperations schema, LabelSchemaDescriptor descriptor) throws TransactionFailureException, CreateConstraintFailureException, DropIndexFailureException, UniquePropertyValueValidationException {
    UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema(descriptor);
    NewIndexDescriptor index = createConstraintIndex(descriptor);
    boolean success = false;
    boolean reacquiredSchemaLock = false;
    Client locks = state.locks().pessimistic();
    try {
        long indexId = schema.indexGetCommittedId(state, index);
        // Release the SCHEMA WRITE lock during index population.
        // At this point the integrity of the constraint to be created was checked
        // while holding the lock and the index rule backing the soon-to-be-created constraint
        // has been created. Now it's just the population left, which can take a long time
        releaseSchemaLock(locks);
        awaitConstrainIndexPopulation(constraint, indexId);
        // Index population was successful, but at this point we don't know if the uniqueness constraint holds.
        // Acquire SCHEMA WRITE lock and verify the constraints here in this user transaction
        // and if everything checks out then it will be held until after the constraint has been
        // created and activated.
        acquireSchemaLock(state, locks);
        reacquiredSchemaLock = true;
        indexingService.getIndexProxy(indexId).verifyDeferredConstraints(propertyAccessor);
        success = true;
        return indexId;
    } catch (SchemaRuleNotFoundException | IndexNotFoundKernelException e) {
        throw new IllegalStateException(String.format("Index (%s) that we just created does not exist.", descriptor));
    } catch (IndexEntryConflictException e) {
        throw new UniquePropertyValueValidationException(constraint, VERIFICATION, e);
    } catch (InterruptedException | IOException e) {
        throw new CreateConstraintFailureException(constraint, e);
    } finally {
        if (!success) {
            if (!reacquiredSchemaLock) {
                acquireSchemaLock(state, locks);
            }
            dropUniquenessConstraintIndex(index);
        }
    }
}
Also used : UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) SchemaRuleNotFoundException(org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException) IndexNotFoundKernelException(org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException) IOException(java.io.IOException) NewIndexDescriptor(org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor) UniquenessConstraintDescriptor(org.neo4j.kernel.api.schema_new.constaints.UniquenessConstraintDescriptor) Client(org.neo4j.kernel.impl.locking.Locks.Client) IndexEntryConflictException(org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException) CreateConstraintFailureException(org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException)

Example 10 with UniquePropertyValueValidationException

use of org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException in project neo4j by neo4j.

the class UniquenessConstraintValidationIT method shouldEnforceUniquenessConstraintOnAddLabelForNumberPropertyOnNodeNotFromTransaction.

@Test
void shouldEnforceUniquenessConstraintOnAddLabelForNumberPropertyOnNodeNotFromTransaction() throws Exception {
    // given
    constrainedNode("Label1", "key1", 1);
    // when
    KernelTransaction transaction = newTransaction(AnonymousContext.writeToken());
    long node = createNode(transaction, "key1", 1);
    commit();
    transaction = newTransaction(AnonymousContext.writeToken());
    try {
        int label = transaction.tokenWrite().labelGetOrCreateForName("Label1");
        transaction.dataWrite().nodeAddLabel(node, label);
        fail("should have thrown exception");
    }// then
     catch (UniquePropertyValueValidationException e) {
        assertThat(e.getUserMessage(transaction.tokenRead())).contains("`key1` = 1");
    }
    commit();
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) Test(org.junit.jupiter.api.Test)

Aggregations

UniquePropertyValueValidationException (org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException)12 Test (org.junit.jupiter.api.Test)5 IndexEntryConflictException (org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException)5 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)4 IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)3 UniquenessConstraintDescriptor (org.neo4j.kernel.api.schema_new.constaints.UniquenessConstraintDescriptor)3 IOException (java.io.IOException)2 TransactionFailureException (org.neo4j.internal.kernel.api.exceptions.TransactionFailureException)2 CreateConstraintFailureException (org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException)2 IndexNotFoundKernelException (org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException)2 IndexNotFoundKernelException (org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException)2 IndexPopulationFailedKernelException (org.neo4j.kernel.api.exceptions.index.IndexPopulationFailedKernelException)2 AlreadyConstrainedException (org.neo4j.kernel.api.exceptions.schema.AlreadyConstrainedException)2 CreateConstraintFailureException (org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException)2 IndexBrokenKernelException (org.neo4j.kernel.api.exceptions.schema.IndexBrokenKernelException)2 UnableToValidateConstraintException (org.neo4j.kernel.api.exceptions.schema.UnableToValidateConstraintException)2 NewIndexDescriptor (org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor)2 IndexProxy (org.neo4j.kernel.impl.api.index.IndexProxy)2 IndexingService (org.neo4j.kernel.impl.api.index.IndexingService)2 Client (org.neo4j.kernel.impl.locking.Locks.Client)2