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

org.hibernate.Session Maven / Gradle / Ivy

The newest version!
/*
 * SPDX-License-Identifier: LGPL-2.1-or-later
 * Copyright Red Hat Inc. and Hibernate Authors
 */
package org.hibernate;

import java.util.List;
import java.util.function.Consumer;

import jakarta.persistence.FindOption;
import org.hibernate.graph.RootGraph;
import org.hibernate.jdbc.Work;
import org.hibernate.query.Query;
import org.hibernate.stat.SessionStatistics;

import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.EntityManager;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;

/**
 * The main runtime interface between a Java application and Hibernate. Represents the
 * notion of a persistence context, a set of managed entity instances associated
 * with a logical transaction.
 * 

* The lifecycle of a {@code Session} is bounded by the beginning and end of the logical * transaction. But a long logical transaction might span several database transactions. *

* The primary purpose of the {@code Session} is to offer create, read, and delete * operations for instances of mapped entity classes. An instance may be in one of three * states with respect to a given open session: *

    *
  • transient: never persistent, and not associated with the {@code Session}, *
  • persistent: currently associated with the {@code Session}, or *
  • detached: previously persistent, but not currently associated with the * {@code Session}. *
*

* At any given time, an instance may be associated with at most one open session. *

* Any instance returned by {@link #get(Class, Object)}, {@link #find(Class, Object)}, * or by a query is persistent. A persistent instance might hold references to other * entity instances, and sometimes these references are proxied by an * intermediate object. When an associated entity has not yet been fetched from the * database, references to the unfetched entity are represented by uninitialized * proxies. The state of an unfetched entity is automatically fetched from the * database when a method of its proxy is invoked, if and only if the proxy is * associated with an open session. Otherwise, {@link #getReference(Object)} may be * used to trade a proxy belonging to a closed session for a new proxy associated * with the current session. *

* A transient instance may be made persistent by calling {@link #persist(Object)}. * A persistent instance may be made detached by calling {@link #detach(Object)}. * A persistent instance may be marked for removal, and eventually made transient, by * calling {@link #remove(Object)}. *

* Persistent instances are held in a managed state by the persistence context. Any * change to the state of a persistent instance is automatically detected and eventually * flushed to the database. This process of automatic change detection is called * dirty checking and can be expensive in some circumstances. Dirty checking * may be disabled by marking an entity as read-only using * {@link #setReadOnly(Object, boolean)} or simply by {@linkplain #detach(Object) evicting} * it from the persistence context. A session may be set to load entities as read-only * {@linkplain #setDefaultReadOnly(boolean) by default}, or this may be controlled at the * {@linkplain Query#setReadOnly(boolean) query level}. *

* The state of a transient or detached instance may be made persistent by copying it to * a persistent instance using {@link #merge(Object)}. All older operations which moved a * detached instance to the persistent state are now deprecated, and clients should now * migrate to the use of {@code merge()}. *

* The persistent state of a managed entity may be refreshed from the database, discarding * all modifications to the object held in memory, by calling {@link #refresh(Object)}. *

* From {@linkplain FlushMode time to time}, a {@linkplain #flush() flush operation} is * triggered, and the session synchronizes state held in memory with persistent state * held in the database by executing SQL {@code insert}, {@code update}, and {@code delete} * statements. Note that SQL statements are often not executed synchronously by the methods * of the {@code Session} interface. If synchronous execution of SQL is desired, the * {@link StatelessSession} allows this. *

* Each managed instance has an associated {@link LockMode}. By default, the session * obtains only {@link LockMode#READ} on an entity instance it reads from the database * and {@link LockMode#WRITE} on an entity instance it writes to the database. This * behavior is appropriate for programs which use optimistic locking. *

    *
  • A different lock level may be obtained by explicitly specifying the mode using * {@link #get(Class, Object, LockMode)}, {@link #find(Class, Object, LockModeType)}, * {@link #refresh(Object, LockMode)}, {@link #refresh(Object, LockModeType)}, or * {@link org.hibernate.query.SelectionQuery#setLockMode(LockModeType)}. *
  • The lock level of a managed instance already held by the session may be upgraded * to a more restrictive lock level by calling {@link #lock(Object, LockMode)} or * {@link #lock(Object, LockModeType)}. *
*

* A persistence context holds hard references to all its entities and prevents them * from being garbage collected. Therefore, a {@code Session} is a short-lived object, * and must be discarded as soon as a logical transaction ends. In extreme cases, * {@link #clear()} and {@link #detach(Object)} may be used to control memory usage. * However, for processes which read many entities, a {@link StatelessSession} should * be used. *

* A session might be associated with a container-managed JTA transaction, or it might be * in control of its own resource-local database transaction. In the case of a * resource-local transaction, the client must demarcate the beginning and end of the * transaction using a {@link Transaction}. A typical resource-local transaction should * use the following idiom: *

 * Session session = factory.openSession();
 * Transaction tx = null;
 * try {
 *     tx = session.beginTransaction();
 *     //do some work
 *     ...
 *     tx.commit();
 * }
 * catch (Exception e) {
 *     if (tx!=null) tx.rollback();
 *     throw e;
 * }
 * finally {
 *     session.close();
 * }
 * 
*

* It's crucially important to appreciate the following restrictions and why they exist: *

    *
  • If the {@code Session} throws an exception, the current transaction must be rolled * back and the session must be discarded. The internal state of the {@code Session} * cannot be expected to be consistent with the database after the exception occurs. *
  • At the end of a logical transaction, the session must be explicitly {@linkplain * #close() destroyed}, so that all JDBC resources may be released. *
  • A {@code Session} is never thread-safe. It contains various different sorts of * fragile mutable state. Each thread or transaction must obtain its own dedicated * instance from the {@link SessionFactory}. *
*

* An easy way to be sure that session and transaction management is being done correctly * is to {@linkplain SessionFactory#inTransaction(Consumer) let the factory do it}: *

 * sessionFactory.inTransaction(session -> {
 *     //do the work
 *     ...
 * });
 * 
*

* A session may be used to {@linkplain #doWork(Work) execute JDBC work} using its JDBC * connection and transaction: *

 * session.doWork(connection -> {
 *     try ( PreparedStatement ps = connection.prepareStatement( " ... " ) ) {
 *         ps.execute();
 *     }
 * });
 * 
*

* A {@code Session} instance is serializable if its entities are serializable. *

* Every {@code Session} is a JPA {@link EntityManager}. Furthermore, when Hibernate is * acting as the JPA persistence provider, the method {@link EntityManager#unwrap(Class)} * may be used to obtain the underlying {@code Session}. *

* Hibernate, unlike JPA, allows a persistence unit where an entity class is mapped multiple * times, with different entity names, usually to different tables. In this case, the session * needs a way to identify the entity name of a given instance of the entity class. Therefore, * some operations of this interface, including operations inherited from {@code EntityManager}, * are overloaded with a form that accepts an explicit entity name along with the instance. An * alternative solution to this problem is to provide an {@link EntityNameResolver}. * * @see SessionFactory * * @author Gavin King * @author Steve Ebersole */ public interface Session extends SharedSessionContract, EntityManager { /** * Force this session to flush. Must be called at the end of a unit of work, * before the transaction is committed. Depending on the current * {@linkplain #setHibernateFlushMode(FlushMode) flush mode}, the session might * automatically flush when {@link Transaction#commit()} is called, and it is not * necessary to call this method directly. *

* Flushing is the process of synchronizing the underlying persistent * store with persistable state held in memory. * * @throws HibernateException if changes could not be synchronized with the database */ @Override void flush(); /** * Set the current {@linkplain FlushModeType JPA flush mode} for this session. *

* Flushing is the process of synchronizing the underlying persistent * store with persistable state held in memory. The current flush mode determines * when the session is automatically flushed. * * @param flushMode the new {@link FlushModeType} * * @see #setHibernateFlushMode(FlushMode) */ @Override void setFlushMode(FlushModeType flushMode); /** * Set the current {@linkplain FlushMode flush mode} for this session. *

* Flushing is the process of synchronizing the underlying persistent * store with persistable state held in memory. The current flush mode determines * when the session is automatically flushed. *

* The {@linkplain FlushMode#AUTO default flush mode} is sometimes unnecessarily * aggressive. For a logically "read only" session, it's reasonable to set the * session's flush mode to {@link FlushMode#MANUAL} at the start of the session * in order to avoid some unnecessary work. *

* Note that {@link FlushMode} defines more options than {@link FlushModeType}. * * @param flushMode the new {@link FlushMode} */ void setHibernateFlushMode(FlushMode flushMode); /** * Get the current {@linkplain FlushModeType JPA flush mode} for this session. * * @return the {@link FlushModeType} currently in effect * * @see #getHibernateFlushMode() */ @Override FlushModeType getFlushMode(); /** * Get the current {@linkplain FlushMode flush mode} for this session. * * @return the {@link FlushMode} currently in effect */ FlushMode getHibernateFlushMode(); /** * Set the current {@linkplain CacheMode cache mode} for this session. *

* The cache mode determines the manner in which this session can interact with * the second level cache. * * @param cacheMode the new cache mode */ void setCacheMode(CacheMode cacheMode); /** * Get the current {@linkplain CacheMode cache mode} for this session. * * @return the current cache mode */ CacheMode getCacheMode(); /** * The JPA-defined {@link CacheStoreMode}. * * @see #getCacheMode() * * @since 6.2 */ @Override CacheStoreMode getCacheStoreMode(); /** * The JPA-defined {@link CacheRetrieveMode}. * * @see #getCacheMode() * * @since 6.2 */ @Override CacheRetrieveMode getCacheRetrieveMode(); /** * Enable or disable writes to the second-level cache. * * @param cacheStoreMode a JPA-defined {@link CacheStoreMode} * * @see #setCacheMode(CacheMode) * * @since 6.2 */ @Override void setCacheStoreMode(CacheStoreMode cacheStoreMode); /** * Enable or disable reads from the second-level cache. * * @param cacheRetrieveMode a JPA-defined {@link CacheRetrieveMode} * * @see #setCacheMode(CacheMode) * * @since 6.2 */ @Override void setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode); /** * Get the maximum batch size for batch fetching associations by * id in this session. * * @since 6.3 */ int getFetchBatchSize(); /** * Set the maximum batch size for batch fetching associations by * id in this session. Override the * {@linkplain org.hibernate.boot.spi.SessionFactoryOptions#getDefaultBatchFetchSize() * factory-level} default controlled by the configuration property * {@value org.hibernate.cfg.AvailableSettings#DEFAULT_BATCH_FETCH_SIZE}. *

*

    *
  • If {@code batchSize>1}, then batch fetching is enabled. *
  • If {@code batchSize<0}, the batch size is inherited from * the factory-level setting. *
  • Otherwise, batch fetching is disabled. *
* * @param batchSize the maximum batch size for batch fetching * * @since 6.3 * * @see org.hibernate.cfg.AvailableSettings#DEFAULT_BATCH_FETCH_SIZE */ void setFetchBatchSize(int batchSize); /** * Determine if subselect fetching is enabled in this session. * * @return {@code true} is subselect fetching is enabled * * @since 6.3 */ boolean isSubselectFetchingEnabled(); /** * Enable or disable subselect fetching in this session. Override the * {@linkplain org.hibernate.boot.spi.SessionFactoryOptions#isSubselectFetchEnabled() * factory-level} default controlled by the configuration property * {@value org.hibernate.cfg.AvailableSettings#USE_SUBSELECT_FETCH}. * * @param enabled {@code true} to enable subselect fetching * * @since 6.3 * * @see org.hibernate.cfg.AvailableSettings#USE_SUBSELECT_FETCH */ void setSubselectFetchingEnabled(boolean enabled); /** * Get the session factory which created this session. * * @return the session factory * * @see SessionFactory */ SessionFactory getSessionFactory(); /** * Cancel the execution of the current query. *

* This is the sole method on session which may be safely called from * another thread. * * @throws HibernateException if there was a problem cancelling the query */ void cancelQuery(); /** * Does this session contain any changes which must be synchronized with * the database? In other words, would any DML operations be executed if * we flushed this session? * * @return {@code true} if the session contains pending changes; {@code false} otherwise. * @throws HibernateException could not perform dirtying checking */ boolean isDirty(); /** * Will entities and proxies that are loaded into this session be made * read-only by default? *

* To determine the read-only/modifiable setting for a particular entity * or proxy use {@link #isReadOnly(Object)}. * * @see #isReadOnly(Object) * * @return {@code true}, loaded entities/proxies will be made read-only by default; * {@code false}, loaded entities/proxies will be made modifiable by default. */ boolean isDefaultReadOnly(); /** * Change the default for entities and proxies loaded into this session * from modifiable to read-only mode, or from modifiable to read-only mode. *

* Read-only entities are not dirty-checked and snapshots of persistent * state are not maintained. Read-only entities can be modified, but * changes are not persisted. *

* When a proxy is initialized, the loaded entity will have the same * read-only/modifiable setting as the uninitialized proxy has, * regardless of the session's current setting. *

* To change the read-only/modifiable setting for a particular entity * or proxy that already belongs to this session use * {@link #setReadOnly(Object, boolean)}. *

* To override this session's read-only/modifiable setting for all * entities and proxies loaded by a certain {@code Query} use * {@link Query#setReadOnly(boolean)}. * * @see #setReadOnly(Object,boolean) * @see Query#setReadOnly(boolean) * * @param readOnly {@code true}, the default for loaded entities/proxies is read-only; * {@code false}, the default for loaded entities/proxies is modifiable */ void setDefaultReadOnly(boolean readOnly); /** * Return the identifier value of the given entity associated with this session. * An exception is thrown if the given entity instance is transient or detached * in relation to this session. * * @param object a persistent instance associated with this session * * @return the identifier * * @throws TransientObjectException if the instance is transient or associated with * a different session */ Object getIdentifier(Object object); /** * Determine if the given entity is associated with this session. * * @param entityName the entity name * @param object an instance of a persistent class * * @return {@code true} if the given instance is associated with this {@code Session} */ boolean contains(String entityName, Object object); /** * Remove this instance from the session cache. Changes to the instance will * not be synchronized with the database. This operation cascades to associated * instances if the association is mapped with * {@link jakarta.persistence.CascadeType#DETACH}. * * @param object the managed instance to detach */ @Override void detach(Object object); /** * Remove this instance from the session cache. Changes to the instance will * not be synchronized with the database. This operation cascades to associated * instances if the association is mapped with * {@link jakarta.persistence.CascadeType#DETACH}. *

* This operation is a synonym for {@link #detach(Object)}. * * @param object the managed entity to evict * * @throws NullPointerException if the passed object is {@code null} * @throws IllegalArgumentException if the passed object is not mapped as an entity */ void evict(Object object); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. *

* The object returned by {@code get()} or {@code find()} is either an unproxied instance * of the given entity class, or a fully-fetched proxy object. *

* This operation requests {@link LockMode#NONE}, that is, no lock, allowing the object * to be retrieved from the cache without the cost of database access. However, if it is * necessary to read the state from the database, the object will be returned with the * lock mode {@link LockMode#READ}. *

* To bypass the {@linkplain Cache second-level cache}, and ensure that the state of the * requested instance is read directly from the database, either: *

    *
  • call {@link #find(Class, Object, FindOption...)}, passing * {@link CacheRetrieveMode#BYPASS} as an option, *
  • call {@link #find(Class, Object, LockMode)} with the explicit lock mode * {@link LockMode#READ}, or *
  • {@linkplain #setCacheRetrieveMode set the cache mode} to * {@link CacheRetrieveMode#BYPASS} before calling this method. *
* * @apiNote This operation is very similar to {@link #get(Class, Object)}. * * @param entityType the entity type * @param id an identifier * * @return a fully-fetched persistent instance or null */ @Override T find(Class entityType, Object id); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. *

* Convenient form of {@link #find(Class, Object, LockOptions)}. * * @param entityType the entity type * @param id an identifier * @param lockMode the lock mode * * @return a fully-fetched persistent instance or null * * @since 7.0 * * @see #find(Class, Object, LockOptions) */ T find(Class entityType, Object id, LockMode lockMode); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. * * @param entityType the entity type * @param id an identifier * @param lockOptions the lock mode * * @return a fully-fetched persistent instance or null * * @since 7.0 */ T find(Class entityType, Object id, LockOptions lockOptions); /** * Return the persistent instances of the given entity class with the given identifiers * as a list. The position of an instance in the returned list matches the position of its * identifier in the given list of identifiers, and the returned list contains a null value * if there is no persistent instance matching a given identifier. If an instance is already * associated with the session, that instance is returned. This method never returns an * uninitialized instance. *

* Every object returned by {@code findMultiple()} is either an unproxied instance of the * given entity class, or a fully-fetched proxy object. *

* This method accepts {@link BatchSize} as an option, allowing control over the number of * records retrieved in a single database request. The performance impact of setting a batch * size depends on whether a SQL array may be used to pass the list of identifiers to the * database: *

    *
  • for databases which {@linkplain org.hibernate.dialect.Dialect#supportsStandardArrays * support standard SQL arrays}, a smaller batch size might be extremely inefficient * compared to a very large batch size or no batching at all, but *
  • on the other hand, for databases with no SQL array type, a large batch size results * in long SQL statements with many JDBC parameters. *
*

* For more advanced cases, use {@link #byMultipleIds(Class)}, which returns an instance of * {@link MultiIdentifierLoadAccess}. * * @param entityType the entity type * @param ids the list of identifiers * @param options options, if any * * @return an ordered list of persistent instances, with null elements representing missing * entities, whose positions in the list match the positions of their ids in the * given list of identifiers * @see #byMultipleIds(Class) * @since 7.0 */ List findMultiple(Class entityType, List ids, FindOption... options); /** * Read the persistent state associated with the given identifier into the given * transient instance. * * @param object a transient instance of an entity class * @param id an identifier */ void load(Object object, Object id); /** * Persist the state of the given detached instance, reusing the current * identifier value. This operation cascades to associated instances if * the association is mapped with * {@link org.hibernate.annotations.CascadeType#REPLICATE}. * * @param object a detached instance of a persistent class * @param replicationMode the replication mode to use * * @deprecated With no real replacement. For some use cases try * {@link StatelessSession#upsert(Object)}. */ @Deprecated( since = "6.0" ) void replicate(Object object, ReplicationMode replicationMode); /** * Persist the state of the given detached instance, reusing the current * identifier value. This operation cascades to associated instances if * the association is mapped with * {@link org.hibernate.annotations.CascadeType#REPLICATE}. * * @param entityName the entity name * @param object a detached instance of a persistent class * @param replicationMode the replication mode to use * * @deprecated With no real replacement. For some use cases try * {@link StatelessSession#upsert(Object)}. */ @Deprecated( since = "6.0" ) void replicate(String entityName, Object object, ReplicationMode replicationMode) ; /** * Copy the state of the given object onto the persistent object with the same * identifier. If there is no persistent instance currently associated with * the session, it will be loaded. Return the persistent instance. If the * given instance is unsaved, save a copy and return it as a newly persistent * instance. The given instance does not become associated with the session. * This operation cascades to associated instances if the association is mapped * with {@link jakarta.persistence.CascadeType#MERGE}. * * @param object a detached instance with state to be copied * * @return an updated persistent instance */ @Override T merge(T object); /** * Copy the state of the given object onto the persistent object with the same * identifier. If there is no persistent instance currently associated with * the session, it will be loaded. Return the persistent instance. If the * given instance is unsaved, save a copy and return it as a newly persistent * instance. The given instance does not become associated with the session. * This operation cascades to associated instances if the association is mapped * with {@link jakarta.persistence.CascadeType#MERGE}. * * @param entityName the entity name * @param object a detached instance with state to be copied * * @return an updated persistent instance */ T merge(String entityName, T object); /** * Make a transient instance persistent and mark it for later insertion in the * database. This operation cascades to associated instances if the association * is mapped with {@link jakarta.persistence.CascadeType#PERSIST}. *

* For an entity with a {@linkplain jakarta.persistence.GeneratedValue generated} * id, {@code persist()} ultimately results in generation of an identifier for * the given instance. But this may happen asynchronously, when the session is * {@linkplain #flush() flushed}, depending on the identifier generation strategy. * * @param object a transient instance to be made persistent */ @Override void persist(Object object); /** * Make a transient instance persistent and mark it for later insertion in the * database. This operation cascades to associated instances if the association * is mapped with {@link jakarta.persistence.CascadeType#PERSIST}. *

* For entities with a {@link jakarta.persistence.GeneratedValue generated id}, * {@code persist()} ultimately results in generation of an identifier for the * given instance. But this may happen asynchronously, when the session is * {@linkplain #flush() flushed}, depending on the identifier generation strategy. * * @param entityName the entity name * @param object a transient instance to be made persistent */ void persist(String entityName, Object object); /** * Obtain the specified lock level on the given managed instance associated * with this session. This operation may be used to: *

    *
  • perform a version check on an entity read from the second-level cache * by requesting {@link LockMode#READ}, *
  • schedule a version check at transaction commit by requesting * {@link LockMode#OPTIMISTIC}, *
  • schedule a version increment at transaction commit by requesting * {@link LockMode#OPTIMISTIC_FORCE_INCREMENT} *
  • upgrade to a pessimistic lock with {@link LockMode#PESSIMISTIC_READ} * or {@link LockMode#PESSIMISTIC_WRITE}, or *
  • immediately increment the version of the given instance by requesting * {@link LockMode#PESSIMISTIC_FORCE_INCREMENT}. *
*

* If the requested lock mode is already held on the given entity, this * operation has no effect. *

* This operation cascades to associated instances if the association is * mapped with {@link org.hibernate.annotations.CascadeType#LOCK}. *

* The modes {@link LockMode#WRITE} and {@link LockMode#UPGRADE_SKIPLOCKED} * are not legal arguments to {@code lock()}. * * @param object a persistent instance associated with this session * @param lockMode the lock level */ void lock(Object object, LockMode lockMode); /** * Obtain a lock on the given managed instance associated with this session, * using the given {@linkplain LockOptions lock options}. *

* This operation cascades to associated instances if the association is * mapped with {@link org.hibernate.annotations.CascadeType#LOCK}. * * @param object a persistent instance associated with this session * @param lockOptions the lock options * * @since 6.2 */ void lock(Object object, LockOptions lockOptions); /** * Reread the state of the given managed instance associated with this session * from the underlying database. This may be useful: *

    *
  • when a database trigger alters the object state upon insert or update, *
  • after {@linkplain #createMutationQuery(String) executing} any HQL update * or delete statement, *
  • after {@linkplain #createNativeMutationQuery(String) executing} a native * SQL statement, or *
  • after inserting a {@link java.sql.Blob} or {@link java.sql.Clob}. *
*

* This operation cascades to associated instances if the association is mapped * with {@link jakarta.persistence.CascadeType#REFRESH}. *

* This operation requests {@link LockMode#READ}. To obtain a stronger lock, * call {@link #refresh(Object, LockMode)}. * * @param object a persistent instance associated with this session */ @Override void refresh(Object object); /** * Reread the state of the given managed instance from the underlying database, * obtaining the given {@link LockMode}. *

* Convenient form of {@link #refresh(Object, LockOptions)} * * @param object a persistent instance associated with this session * @param lockMode the lock mode to use * * @see #refresh(Object, LockOptions) */ void refresh(Object object, LockMode lockMode); /** * Reread the state of the given managed instance from the underlying database, * obtaining the given {@link LockMode}. * * @param object a persistent instance associated with this session * @param lockOptions contains the lock mode to use */ void refresh(Object object, LockOptions lockOptions); /** * Mark a persistence instance associated with this session for removal from * the underlying database. Ths operation cascades to associated instances if * the association is mapped {@link jakarta.persistence.CascadeType#REMOVE}. *

* Except when operating in fully JPA-compliant mode, this operation does, * contrary to the JPA specification, accept a detached entity instance. * * @param object the managed persistent instance to remove, or a detached * instance unless operating in fully JPA-compliant mode */ @Override void remove(Object object); /** * Determine the current {@link LockMode} of the given managed instance associated * with this session. * * @param object a persistent instance associated with this session * * @return the current lock mode */ LockMode getCurrentLockMode(Object object); /** * Completely clear the session. Evict all loaded instances and cancel all pending * saves, updates and deletions. Do not close open iterators or instances of * {@link ScrollableResults}. */ @Override void clear(); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. *

* The object returned by {@code get()} or {@code find()} is either an unproxied instance * of the given entity class, or a fully-fetched proxy object. *

* This operation requests {@link LockMode#NONE}, that is, no lock, allowing the object * to be retrieved from the cache without the cost of database access. However, if it is * necessary to read the state from the database, the object will be returned with the * lock mode {@link LockMode#READ}. *

* To bypass the second-level cache, and ensure that the state is read from the database, * either: *

    *
  • call {@link #get(Class, Object, LockMode)} with the explicit lock mode * {@link LockMode#READ}, or *
  • {@linkplain #setCacheMode set the cache mode} to {@link CacheMode#IGNORE} * before calling this method. *
* * @apiNote This operation is very similar to {@link #find(Class, Object)}. * * @param entityType the entity type * @param id an identifier * * @return a persistent instance or null * * @deprecated Because the semantics of this method may change in a future release. * Use {@link #find(Class, Object)} instead. */ @Deprecated(since = "7") T get(Class entityType, Object id); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. *

* Convenient form of {@link #get(Class, Object, LockOptions)}. * * @apiNote This operation is very similar to {@link #find(Class, Object, LockModeType)}. * * @param entityType the entity type * @param id an identifier * @param lockMode the lock mode * * @return a persistent instance or null * * @see #get(Class, Object, LockOptions) * * @deprecated The semantics of this method may change in a future release. * Use {@link #find(Class, Object, LockMode)} instead. */ @Deprecated(since = "7") T get(Class entityType, Object id, LockMode lockMode); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. * * @param entityType the entity type * @param id an identifier * @param lockOptions the lock mode * * @return a persistent instance or null * * @deprecated The semantics of this method may change in a future release. * Use {@link #find(Class, Object, LockOptions)} instead. */ @Deprecated(since = "7") T get(Class entityType, Object id, LockOptions lockOptions); /** * Return the persistent instance of the given named entity with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. * * @param entityName the entity name * @param id an identifier * * @return a persistent instance or null * * @deprecated The semantics of this method may change in a future release. */ @Deprecated(since = "7") Object get(String entityName, Object id); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. *

* Convenient form of {@link #get(String, Object, LockOptions)} * * @param entityName the entity name * @param id an identifier * @param lockMode the lock mode * * @return a persistent instance or null * * @see #get(String, Object, LockOptions) * * @deprecated The semantics of this method may change in a future release. */ @Deprecated(since = "7") Object get(String entityName, Object id, LockMode lockMode); /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. If the instance is already associated * with the session, return that instance. This method never returns an uninitialized * instance. Obtain the specified lock mode if the instance exists. * * @param entityName the entity name * @param id an identifier * @param lockOptions contains the lock mode * * @return a persistent instance or null * * @deprecated The semantics of this method may change in a future release. */ @Deprecated(since = "7") Object get(String entityName, Object id, LockOptions lockOptions); /** * Return the entity name for a persistent entity. * * @param object a persistent entity associated with this session * * @return the entity name */ String getEntityName(Object object); /** * Return a reference to the persistent instance with the given class and identifier, * making the assumption that the instance is still persistent in the database. This * method never results in access to the underlying data store, and thus might return * a proxy that is initialized on-demand, when a non-identifier method is accessed. *

* Note that {@link Hibernate#createDetachedProxy(SessionFactory, Class, Object)} * may be used to obtain a detached reference. *

* It's sometimes necessary to narrow a reference returned by {@code getReference()} * to a subtype of the given entity type. A direct Java typecast should never be used * in this situation. Instead, the method {@link Hibernate#unproxy(Object, Class)} is * the recommended way to narrow the type of a proxy object. Alternatively, a new * reference may be obtained by simply calling {@code getReference()} again, passing * the subtype. Either way, the narrowed reference will usually not be identical to * the original reference, when the references are compared using the {@code ==} * operator. * * @param entityType the entity type * @param id the identifier of a persistent instance that exists in the database * * @return the persistent instance or proxy */ @Override T getReference(Class entityType, Object id); /** * Return a reference to the persistent instance of the given named entity with the * given identifier, making the assumption that the instance is still persistent in * the database. This method never results in access to the underlying data store, * and thus might return a proxy that is initialized on-demand, when a non-identifier * method is accessed. * * @param entityName the entity name * @param id the identifier of a persistent instance that exists in the database * * @return the persistent instance or proxy */ Object getReference(String entityName, Object id); /** * Return a reference to the persistent instance with the same identity as the given * instance, which might be detached, making the assumption that the instance is still * persistent in the database. This method never results in access to the underlying * data store, and thus might return a proxy that is initialized on-demand, when a * non-identifier method is accessed. * * @param object a detached persistent instance * * @return the persistent instance or proxy * * @since 6.0 */ @Override T getReference(T object); /** * Create an {@link IdentifierLoadAccess} instance to retrieve an instance of the given * entity type by its primary key. * * @param entityClass the entity type to be retrieved * * @return an instance of {@link IdentifierLoadAccess} for executing the lookup * * @throws HibernateException If the given class does not resolve as a mapped entity */ IdentifierLoadAccess byId(Class entityClass); /** * Create an {@link IdentifierLoadAccess} instance to retrieve an instance of the named * entity type by its primary key. * * @param entityName the entity name of the entity type to be retrieved * * @return an instance of {@link IdentifierLoadAccess} for executing the lookup * * @throws HibernateException If the given name does not resolve to a mapped entity */ IdentifierLoadAccess byId(String entityName); /** * Create a {@link MultiIdentifierLoadAccess} instance to retrieve multiple instances * of the given entity type by their primary key values, using batching. * * @param entityClass the entity type to be retrieved * * @return an instance of {@link MultiIdentifierLoadAccess} for executing the lookup * * @throws HibernateException If the given class does not resolve as a mapped entity * * @see #findMultiple(Class, List, FindOption...) */ MultiIdentifierLoadAccess byMultipleIds(Class entityClass); /** * Create a {@link MultiIdentifierLoadAccess} instance to retrieve multiple instances * of the named entity type by their primary key values, using batching. * * @param entityName the entity name of the entity type to be retrieved * * @return an instance of {@link MultiIdentifierLoadAccess} for executing the lookup * * @throws HibernateException If the given name does not resolve to a mapped entity */ MultiIdentifierLoadAccess byMultipleIds(String entityName); /** * Create a {@link NaturalIdLoadAccess} instance to retrieve an instance of the given * entity type by its {@linkplain org.hibernate.annotations.NaturalId natural id}, * which may be a composite natural id. The entity must have at least one attribute * annotated {@link org.hibernate.annotations.NaturalId}. * * @param entityClass the entity type to be retrieved * * @return an instance of {@link NaturalIdLoadAccess} for executing the lookup * * @throws HibernateException If the given class does not resolve as a mapped entity, * or if the entity does not declare a natural id */ NaturalIdLoadAccess byNaturalId(Class entityClass); /** * Create a {@link NaturalIdLoadAccess} instance to retrieve an instance of the named * entity type by its {@linkplain org.hibernate.annotations.NaturalId natural id}, * which may be a composite natural id. The entity must have at least one attribute * annotated {@link org.hibernate.annotations.NaturalId}. * * @param entityName the entity name of the entity type to be retrieved * * @return an instance of {@link NaturalIdLoadAccess} for executing the lookup * * @throws HibernateException If the given name does not resolve to a mapped entity, * or if the entity does not declare a natural id */ NaturalIdLoadAccess byNaturalId(String entityName); /** * Create a {@link SimpleNaturalIdLoadAccess} instance to retrieve an instance of the * given entity type by its {@linkplain org.hibernate.annotations.NaturalId natural id}, * which must be a simple (non-composite) value. The entity must have exactly one * attribute annotated {@link org.hibernate.annotations.NaturalId}. * * @param entityClass the entity type to be retrieved * * @return an instance of {@link SimpleNaturalIdLoadAccess} for executing the lookup * * @throws HibernateException If the given class does not resolve as a mapped entity, * or if the entity does not declare a natural id */ SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass); /** * Create a {@link SimpleNaturalIdLoadAccess} instance to retrieve an instance of the * named entity type by its {@linkplain org.hibernate.annotations.NaturalId natural id}, * which must be a simple (non-composite) value. The entity must have exactly one * attribute annotated {@link org.hibernate.annotations.NaturalId}. * * @param entityName the entity name of the entity type to be retrieved * * @return an instance of {@link SimpleNaturalIdLoadAccess} for executing the lookup * * @throws HibernateException If the given name does not resolve to a mapped entity, * or if the entity does not declare a natural id */ SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName); /** * Create a {@link MultiIdentifierLoadAccess} instance to retrieve multiple instances * of the given entity type by their by {@linkplain org.hibernate.annotations.NaturalId * natural id} values, using batching. * * @param entityClass the entity type to be retrieved * * @return an instance of {@link NaturalIdMultiLoadAccess} for executing the lookup * * @throws HibernateException If the given class does not resolve as a mapped entity, * or if the entity does not declare a natural id */ NaturalIdMultiLoadAccess byMultipleNaturalId(Class entityClass); /** * Create a {@link MultiIdentifierLoadAccess} instance to retrieve multiple instances * of the named entity type by their by {@linkplain org.hibernate.annotations.NaturalId * natural id} values, using batching. * * @param entityName the entity name of the entity type to be retrieved * * @return an instance of {@link NaturalIdMultiLoadAccess} for executing the lookup * * @throws HibernateException If the given name does not resolve to a mapped entity, * or if the entity does not declare a natural id */ NaturalIdMultiLoadAccess byMultipleNaturalId(String entityName); /** * Get the {@linkplain SessionStatistics statistics} for this session. * * @return the session statistics being collected for this session */ SessionStatistics getStatistics(); /** * Is the specified entity or proxy read-only? *

* To get the default read-only/modifiable setting used for * entities and proxies that are loaded into the session use * {@link #isDefaultReadOnly()} * * @see #isDefaultReadOnly() * * @param entityOrProxy an entity or proxy * @return {@code true} if the entity or proxy is read-only, * {@code false} if the entity or proxy is modifiable. */ boolean isReadOnly(Object entityOrProxy); /** * Set an unmodified persistent object to read-only mode, or a read-only * object to modifiable mode. In read-only mode, no snapshot is maintained, * the instance is never dirty checked, and changes are not persisted. *

* If the entity or proxy already has the specified read-only/modifiable * setting, then this method does nothing. *

* To set the default read-only/modifiable setting used for all entities * and proxies that are loaded into the session use * {@link #setDefaultReadOnly(boolean)}. *

* To override this session's read-only/modifiable setting for entities * and proxies loaded by a {@code Query} use * {@link Query#setReadOnly(boolean)} * * @see #setDefaultReadOnly(boolean) * @see Query#setReadOnly(boolean) * @see IdentifierLoadAccess#withReadOnly(boolean) * * @param entityOrProxy an entity or proxy * @param readOnly {@code true} if the entity or proxy should be made read-only; * {@code false} if the entity or proxy should be made modifiable */ void setReadOnly(Object entityOrProxy, boolean readOnly); /** * Is the {@link org.hibernate.annotations.FetchProfile fetch profile} * with the given name enabled in this session? * * @param name the name of the profile * @return True if fetch profile is enabled; false if not. * * @throws UnknownProfileException Indicates that the given name does not * match any known fetch profile names * * @see org.hibernate.annotations.FetchProfile */ boolean isFetchProfileEnabled(String name) throws UnknownProfileException; /** * Enable the {@link org.hibernate.annotations.FetchProfile fetch profile} * with the given name in this session. If the requested fetch profile is * already enabled, the call has no effect. * * @param name the name of the fetch profile to be enabled * * @throws UnknownProfileException Indicates that the given name does not * match any known fetch profile names * * @see org.hibernate.annotations.FetchProfile */ void enableFetchProfile(String name) throws UnknownProfileException; /** * Disable the {@link org.hibernate.annotations.FetchProfile fetch profile} * with the given name in this session. If the requested fetch profile is * not currently enabled, the call has no effect. * * @param name the name of the fetch profile to be disabled * * @throws UnknownProfileException Indicates that the given name does not * match any known fetch profile names * * @see org.hibernate.annotations.FetchProfile */ void disableFetchProfile(String name) throws UnknownProfileException; /** * Obtain a {@linkplain LobHelper factory} for instances of {@link java.sql.Blob} * and {@link java.sql.Clob}. * * @return an instance of {@link LobHelper} */ LobHelper getLobHelper(); /** * Obtain a {@link Session} builder with the ability to copy certain information * from this session. * * @return the session builder */ SharedSessionBuilder sessionWithOptions(); /** * Add one or more listeners to the Session * * @param listeners the listener(s) to add */ void addEventListeners(SessionEventListener... listeners); @Override RootGraph createEntityGraph(Class rootType); @Override RootGraph createEntityGraph(String graphName); @Override RootGraph getEntityGraph(String graphName); @Override List> getEntityGraphs(Class entityClass); // The following overrides should not be necessary, // and are only needed to work around a bug in IntelliJ @Override Query createQuery(String queryString, Class resultClass); @Override Query createQuery(TypedQueryReference typedQueryReference); @Override @Deprecated @SuppressWarnings("rawtypes") Query createQuery(String queryString); @Override Query createNamedQuery(String name, Class resultClass); @Override @Deprecated @SuppressWarnings("rawtypes") Query createNamedQuery(String name); @Override Query createQuery(CriteriaQuery criteriaQuery); /** * Create a {@link Query} for the given JPA {@link CriteriaDelete}. * * @deprecated use {@link #createMutationQuery(CriteriaDelete)} */ @Override @Deprecated(since = "6.0") @SuppressWarnings("rawtypes") Query createQuery(CriteriaDelete deleteQuery); /** * Create a {@link Query} for the given JPA {@link CriteriaUpdate}. * * @deprecated use {@link #createMutationQuery(CriteriaUpdate)} */ @Override @Deprecated(since = "6.0") @SuppressWarnings("rawtypes") Query createQuery(CriteriaUpdate updateQuery); }