Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/FindBy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;

import jakarta.persistence.FindOption;

/// FindOption allowing to load based on either id (default)
/// or natural-id.
///
/// @see jakarta.persistence.EntityManager#find
/// @see Session#findMultiple
///
/// @author Steve Ebersole
/// @author Gavin King
public enum FindBy implements FindOption {
/// Indicates to find by the entity's identifier. The default.
///
/// @see jakarta.persistence.Id
/// @see jakarta.persistence.EmbeddedId
/// @see jakarta.persistence.IdClass
ID,

/// Indicates to find based on the entity's natural-id, if one.
///
/// @see org.hibernate.annotations.NaturalId
/// @see org.hibernate.annotations.NaturalIdClass
///
/// @implSpec Will trigger an [IllegalArgumentException] if the entity does
/// not define a natural-id.
NATURAL_ID
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package org.hibernate;

import jakarta.persistence.EntityGraph;

import jakarta.persistence.PessimisticLockScope;
import jakarta.persistence.Timeout;
import jakarta.persistence.metamodel.SingularAttribute;
Expand Down Expand Up @@ -35,7 +34,10 @@
* @see Session#byNaturalId(Class)
* @see org.hibernate.annotations.NaturalId
* @see SimpleNaturalIdLoadAccess
*
* @deprecated (since 7.3) Use {@linkplain Session#findByNaturalId} instead.
*/
@Deprecated
public interface NaturalIdLoadAccess<T> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
*
* @see Session#byMultipleNaturalId(Class)
* @see org.hibernate.annotations.NaturalId
*
* @deprecated (since 7.3) Use {@linkplain Session#findMultipleByNaturalId} instead.
*/
@Deprecated
public interface NaturalIdMultiLoadAccess<T> {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;

import jakarta.persistence.FindOption;

/// Indicates whether to perform synchronization (a sort of flush)
/// before a [find by natural-id][FindBy#NATURAL_ID].
///
/// @author Steve Ebersole
public enum NaturalIdSynchronization implements FindOption {
/// Perform the synchronization.
ENABLED,

/// Do not perform the synchronization.
DISABLED;
}
2,436 changes: 1,133 additions & 1,303 deletions hibernate-core/src/main/java/org/hibernate/Session.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
* @see Session#bySimpleNaturalId(Class)
* @see org.hibernate.annotations.NaturalId
* @see NaturalIdLoadAccess
*
* @deprecated (since 7.3) Use {@linkplain Session#findByNaturalId} instead.
*/
@Deprecated
public interface SimpleNaturalIdLoadAccess<T> {

/**
Expand Down
13 changes: 13 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/Timeouts.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,17 @@
}
return Integer.parseInt( factoryHint.toString() );
}

static Timeout fromHintTimeout(Object factoryHint) {
if ( factoryHint == null ) {
return WAIT_FOREVER;
}
if ( factoryHint instanceof Timeout timeout ) {
return timeout;
}
if ( factoryHint instanceof Integer number ) {
return Timeout.milliseconds( number );
}
return Timeout.milliseconds( Integer.parseInt( factoryHint.toString() ) );

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.
}
}
156 changes: 82 additions & 74 deletions hibernate-core/src/main/java/org/hibernate/annotations/NaturalId.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,87 +4,95 @@
*/
package org.hibernate.annotations;


import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Specifies that a field or property of an entity class is part of
* the natural id of the entity. This annotation is very useful when
* the primary key of an entity class is a surrogate key, that is,
* a {@linkplain jakarta.persistence.GeneratedValue system-generated}
* synthetic identifier, with no domain-model semantics. There should
* always be some other field or combination of fields which uniquely
* identifies an instance of the entity from the point of view of the
* user of the system. This is the <em>natural id</em> of the entity.
* <p>
* A natural id may be a single field or property of the entity:
* <pre>
* &#64;Entity
* &#64;Cache &#64;NaturalIdCache
* class Person {
*
* //synthetic id
* &#64;GeneratedValue @Id
* Long id;
*
* &#64;NotNull
* String name;
*
* //simple natural id
* &#64;NotNull @NaturalId
* String ssn;
*
* ...
* }
* </pre>
* <p>
* or it may be a composite value:
* <pre>
* &#64;Entity
* &#64;Cache &#64;NaturalIdCache
* class Vehicle {
*
* //synthetic id
* &#64;GeneratedValue @Id
* Long id;
*
* //composite natural id
*
* &#64;Enumerated
* &#64;NotNull &#64;NaturalId
* Region region;
*
* &#64;NotNull &#64;NaturalId
* String registration;
*
* ...
* }
* </pre>
* <p>
* Unlike the {@linkplain jakarta.persistence.Id primary identifier}
* of an entity, a natural id may be {@linkplain #mutable}.
* <p>
* On the other hand, a field or property which forms part of a natural
* id may never be null, and so it's a good idea to use {@code @NaturalId}
* in conjunction with the Bean Validation {@code @NotNull} annotation
* or {@link jakarta.persistence.Basic#optional @Basic(optional=false)}.
* <p>
* The {@link org.hibernate.Session} interface offers several methods
* that allow an entity instance to be retrieved by its
* {@linkplain org.hibernate.Session#bySimpleNaturalId(Class) simple}
* or {@linkplain org.hibernate.Session#byNaturalId(Class) composite}
* natural id value. If the entity is also marked for {@linkplain
* NaturalIdCache natural id caching}, then these methods may be able
* to avoid a database round trip.
*
* @author Nicolás Lichtmaier
*
* @see NaturalIdCache
*/
/// Specifies that a field or property of an entity class is part of
/// the natural id of the entity. This annotation is very useful when
/// the primary key of an entity class is a surrogate key, that is,
/// a {@linkplain jakarta.persistence.GeneratedValue system-generated}
/// synthetic identifier, with no domain-model semantics. There should
/// always be some other field or combination of fields which uniquely
/// identifies an instance of the entity from the point of view of the
/// user of the system. This is the _natural id_ of the entity.
///
/// A natural id may be a single (basic or embedded) attribute of the entity:
/// ````java
/// @Entity
/// class Person {
///
/// //synthetic id
/// @GeneratedValue @Id
/// Long id;
///
/// @NotNull
/// String name;
///
/// //simple natural id
/// @NotNull @NaturalId
/// String ssn;
///
/// ...
/// }
/// ```
///
/// or it may be a non-aggregated composite value:
/// ```java
/// @Entity
/// class Vehicle {
///
/// //synthetic id
/// @GeneratedValue @Id
/// Long id;
///
/// //composite natural id
///
/// @Enumerated
/// @NotNull
/// @NaturalId
/// Region region;
///
/// @NotNull
/// @NaturalId
/// String registration;
///
/// ...
/// }
/// ```
///
/// Unlike the {@linkplain jakarta.persistence.Id primary identifier}
/// of an entity, a natural id may be {@linkplain #mutable}.
///
/// On the other hand, a field or property which forms part of a natural
/// id may never be null, and so it's a good idea to use `@NaturalId`
/// in conjunction with the Bean Validation `@NotNull` annotation
/// or [@Basic(optional=false)][jakarta.persistence.Basic#optional()].
///
/// The [org.hibernate.Session] interface offers several methods
/// that allow retrieval of one or more entity references by natural-id
/// allow an entity instance to be retrieved by its natural-id:
/// * [org.hibernate.Session#findByNaturalId] allows loading a single
/// entity instance by natural-id.
/// * [org.hibernate.Session#findMultipleByNaturalId] allows loading multiple
/// entity instances by natural-id.
///
/// If the entity is also marked for [natural id caching][NaturalIdCache],
/// then these methods may be able to avoid a database round trip.
///
/// @see org.hibernate.Session#findByNaturalId
/// @see org.hibernate.Session#findMultipleByNaturalId
/// @see NaturalIdClass
/// @see NaturalIdCache
///
/// @apiNote For non-aggregated composite natural-id cases, it is recommended to
/// leverage [@NaturalIdClass][NaturalIdClass] for loading.
///
/// @author Nicolás Lichtmaier
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface NaturalId {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.annotations;

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

/// Models a non-aggregated composite natural-id for the purpose of loading.
/// The non-aggregated form uses multiple [@NaturalId][NaturalId] as opposed
/// to the aggregated form which uses a single [@NaturalId][NaturalId] combined
/// with [@Embedded][jakarta.persistence.Embedded].
/// Functions in a similar fashion as [@IdClass][jakarta.persistence.IdClass] for
/// non-aggregated composite identifiers.
///
/// ```java
/// @Entity
/// @NaturalIdClass(OrderNaturalId.class)
/// class Order {
/// @Id
/// Integer id;
/// @NaturalId @ManyToOne
/// Customer customer;
/// @NaturalId
/// Integer orderNumber;
/// ...
/// }
///
/// class OrderNaturalId {
/// Integer customer;
/// Integer orderNumber;
/// ...
/// }
/// ```
///
/// @see NaturalId
/// @see jakarta.persistence.IdClass
///
/// @author Steve Ebersole
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NaturalIdClass {
/// The class to use for loading the associated entity by natural-id.
Class<?> value();
}
Loading
Loading