All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.annotation.PermazenCompositeIndex Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.annotation;

import io.permazen.PermazenObject;
import io.permazen.UniquenessConstraints;

import jakarta.validation.groups.Default;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Java annotation that defines a composite index.
 *
 * 

* A composite index is an index on two or more fields (to define a single-field index, see {@link PermazenField#indexed}). * All fields participating in a composite index must be (a) simple and (b) not a sub-field of a complex field. * *

* The class or interface does not have to be {@link PermazenType @PermazenType}-annotated; annotations * are "inherited" and so apply to all {@link PermazenType @PermazenType}-annotated sub-types. * *

* {@link PermazenCompositeIndex @PermazenCompositeIndex} is a {@linkplain Repeatable repeatable annotation}. * *

Uniqueness Constraints

* * Uniqueness constraints are supported, and their enforcement is handled in the same way as for uniqueness constraints * on simply indexed fields (see {@link PermazenField#unique @PermazenField.unique()}). A uniqueness constriant on a composite * index means each combination of field values must be unique to a single object. Specific field value combinations may be * excluded from the uniqueness constraint by specifying the corresponding comma-separated {@link String}-encoded tuples * in {@link #uniqueExcludes}. * * @see PermazenType * @see PermazenField#indexed */ @Repeatable(PermazenCompositeIndexes.class) @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) @Documented public @interface PermazenCompositeIndex { /** * The name of this index. * *

* The name must be unique among all other indexes and simple fields in a Java model type. * * @return the index name */ String name(); /** * Storage ID for this index. * *

* Normally this value is left as zero, in which case a value will be automatically assigned. * *

* Otherwise, the value should be positive and unique within the schema. * * @return this index's storage ID, or zero for automatic assignment */ int storageId() default 0; /** * The names of the indexed fields, in the desired order. At least two fields must be specified. * * @return the names of the indexed fields */ String[] fields(); /** * Require each object's field combination to be unique among all types to which this annotation applies. * *

* This property creates an implicit uniqueness validation constraint. * *

* The constraint will be checked any time normal validation is performed on an object. * More precisely, a uniqueness constraint behaves like a JSR 303 * validation constraint with {@code groups() = }{ {@link Default}{@code .class, * }{@link UniquenessConstraints}{@code .class} }. Therefore, uniqueness constraints * are included in default validation, but you can also validate only uniqueness constraints via * {@link PermazenObject#revalidate myobj.revalidate(UniquenessConstraints.class)}. * * @return whether the composite index's field values should be unique * @see #uniqueExcludes * @see UniquenessConstraints */ boolean unique() default false; /** * Specify field value combinations to be excluded from the uniqueness constraint. * *

* The annotation value is a list of {@link ValuesList @ValuesList} annotations, each of which describes some * combination of field values that should grant the containing object exclusion from the uniqueness constraint. * *

* Each {@link ValuesList @ValuesList} contains a list of {@link Values @Values} annotations, one for each field * in the index. For an object to be excluded from the uniqueness constraint, the object's fields' values must all * match their corresponding {@link Values @Values} annotation in at least one of the * {@link ValuesList @ValuesList} annotations. * *

* For example, consider this class: *

     *  public abstract class Person {
     *
     *      public abstract String getName();
     *      public abstract void setName(String x);
     *
     *      public abstract int getId();
     *      public abstract void setId(int x);
     *  }
     * 
* *

* To require a {@code Person}'s name and ID combination to be unique, but exclude * {@code Person}'s whose name is null and whose ID is equal to -1 or -2: * *

     * @PermazenType(compositeIndexes =
     *  @PermazenCompositeIndex(name = "nameAndId", fields = { "name", "id" },
     *      unique = true,
     *      uniqueExcludes = @ValuesList({ @Values(nulls = true), @Values({ "-1", "-2" }) })
     *  ))))
     *  public abstract class Person {
     *      ...
     *  }
     * 
* *

* To require a {@code Person}'s name and ID combination to be unique, but exclude * {@code Person}'s whose name is null or whose ID is equal to -1 or -2: * *

     * @PermazenType(compositeIndexes =
     *  @PermazenCompositeIndex(name = "nameAndId", fields = { "name", "id" },
     *      unique = true,
     *      uniqueExcludes = {
     *          @ValuesList({ @Values(nulls = true), @Values(nonNulls = true) }),
     *          @ValuesList({ @Values(nulls = true, nonNulls = true), @Values({ "-1", "-2" }) })
     *  }))))
     *  public abstract class Person {
     *      ...
     *  }
     * 
* *

* Notes: *

    *
  • To match all possible values for a field, use {@link Values @Values}{@code (nulls = true, nonNulls = true)} *
  • For primitive fields, {@link Values#nulls @Values.nulls()} is not relevant. *
* *

* It is an error if, for any {@link ValuesList @ValuesList}, every possible field combination * would match, as this would pointlessly exclude every object. * *

* This property must be left empty when {@link #unique} is false. * * @return field value combinations to exclude from the uniqueness constraint * @see #unique */ ValuesList[] uniqueExcludes() default {}; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy