org.hibernate.annotations.Any Maven / Gradle / Ivy
Show all versions of beangle-hibernate-core Show documentation
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.persistence.FetchType;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Maps a to-one cardinality association taking values over several entity types which
* are not related by the usual entity inheritance, using a discriminator
* value stored on the referring side of the relationship.
*
* This is quite different to
* {@linkplain jakarta.persistence.InheritanceType#SINGLE_TABLE discriminated inheritance}
* where the discriminator is stored along with the referenced entity hierarchy.
*
* For example, consider an {@code Order} entity containing {@code Payment} information,
* where a {@code Payment} might be a {@code CashPayment} or a {@code CreditCardPayment}.
* An {@code @Any} mapping would store the discriminator value identifying the concrete
* type of {@code Payment} along with the state of the associated {@code Order}, instead
* of storing it with the {@code Payment} entity itself.
*
* interface Payment { ... }
*
* @Entity
* class CashPayment { ... }
*
* @Entity
* class CreditCardPayment { ... }
*
* @Entity
* class Order {
* ...
* @Any
* @JoinColumn(name="payment_id") //the foreign key column
* @Column(name="payment_type") //the discriminator column
* @AnyDiscriminatorValue(discriminator="CASH", entity=CashPayment.class)
* @AnyDiscriminatorValue(discriminator="CREDIT", entity=CreditCardPayment.class)
* Payment payment;
* ...
* }
*
*
* In this example, {@code Payment} is not be declared as an entity type, and
* is not annotated {@link jakarta.persistence.Entity @Entity}. It might even be an
* interface, or at most just a {@linkplain jakarta.persistence.MappedSuperclass mapped
* superclass}, of {@code CashPayment} and {@code CreditCardPayment}. So in terms of the
* object/relational mappings, {@code CashPayment} and {@code CreditCardPayment} would
* not be considered to participate in the same entity inheritance hierarchy.
* On the other hand, {@code CashPayment} and {@code CreditCardPayment} must have the
* same identifier type.
*
* It's reasonable to think of the "foreign key" in an {@code Any} mapping is really a
* composite value made up of the foreign key and discriminator taken together. Note,
* however, that this composite foreign key is only conceptual and cannot be declared
* as a physical constraint on the relational database table.
*
* - {@link AnyDiscriminator}, {@link JdbcType}, or {@link JdbcTypeCode} specifies
* the type of the discriminator.
*
- {@link AnyDiscriminatorValue} specifies how discriminator values map to entity
* types.
*
- {@link jakarta.persistence.Column} or {@link Formula} specifies the column or
* formula in which the discriminator value is stored.
*
- {@link AnyKeyJavaType}, {@link AnyKeyJavaClass}, {@link AnyKeyJdbcType}, or
* {@link AnyKeyJdbcTypeCode} specifies the type of the foreign key.
*
- {@link jakarta.persistence.JoinColumn} specifies the foreign key column.
*
*
* Of course, {@code Any} mappings are disfavored, except in extremely special cases,
* since it's much more difficult to enforce referential integrity at the database
* level.
*
* @see ManyToAny
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Any {
/**
* Specifies whether the value of the field or property may be lazily loaded or must
* be eagerly fetched:
*
* - {@link FetchType#EAGER EAGER} specifies that the association must be eagerly
* fetched.
*
- {@link FetchType#LAZY LAZY} allows the association to be fetched lazily, but
* this is possible only when bytecode enhancement is used.
*
*
* If not explicitly specified, the default is {@code EAGER}.
*/
FetchType fetch() default FetchType.EAGER;
/**
* Whether the association is optional.
*
* If the discriminator {@link jakarta.persistence.Column Column} or the
* {@link jakarta.persistence.JoinColumn JoinColumn} are not nullable the
* association is always considered non-optional, regardless of this value.
*
* @return {@code false} if the association cannot be null.
*/
boolean optional() default true;
}