Skip to content

Commit

Permalink
introduce ManagedEntityMode
Browse files Browse the repository at this point in the history
finally addresses issue jakartaee#62

Signed-off-by: Gavin King <[email protected]>
  • Loading branch information
gavinking committed Sep 20, 2024
1 parent 1aac75c commit 8ddac32
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 3 deletions.
21 changes: 21 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,27 @@ void refresh(Object entity,
*/
void clear();

/**
* Obtain the {@link ManagedEntityMode} of the given entity.
* @param entity a persistent entity associated with the
* persistence context
* @throws IllegalArgumentException if the instance is not an entity
* or if the entity is not managed
* @since 4.0
*/
ManagedEntityMode getManagedEntityMode(Object entity);

/**
* Set the {@link ManagedEntityMode} of the given entity.
* @param entity a persistent entity associated with the
* persistence context
* @param mode the new mode
* @throws IllegalArgumentException if the instance is not an entity
* or if the entity is not managed
* @since 4.0
*/
void setManagedEntityMode(Object entity, ManagedEntityMode mode);

/**
* Evict the given managed or removed entity from the persistence
* context, causing the entity to become immediately detached.
Expand Down
41 changes: 41 additions & 0 deletions api/src/main/java/jakarta/persistence/ManagedEntityMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2008, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Gavin King - 4.0

package jakarta.persistence;

/**
* A {@link FindOption} which specifies whether entities are
* to be loaded in {@linkplain #READ_ONLY read only} mode or
* in regular {@linkplain #READ_WRITE modifiable} mode.
*
* @since 4.0
*/
public enum ManagedEntityMode implements FindOption {
/**
* Specifies that an entity should be loaded in read-only mode.
* <p>
* Read-only entities can be modified, but changes are not
* synchronized with the database.
*/
READ_ONLY,
/**
* Specifies that an entity should be loaded in the default
* modifiable mode.
* <p>
* Changes made to modifiable entities are synchronized to
* with the database when the persistence context is flushed.
*/
READ_WRITE
}
7 changes: 7 additions & 0 deletions api/src/main/java/jakarta/persistence/NamedNativeQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@
*/
String query();

/**
* (Optional) The {@link ManagedEntityMode} to use for entities
* loaded during execution of the query.
* @since 4.0
*/
ManagedEntityMode managedEntityMode() default ManagedEntityMode.READ_WRITE;

/**
* Query properties and hints.
* (May include vendor-specific query hints.)
Expand Down
9 changes: 8 additions & 1 deletion api/src/main/java/jakarta/persistence/NamedQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,14 @@
* @since 2.0
*/
LockModeType lockMode() default LockModeType.NONE;


/**
* (Optional) The {@link ManagedEntityMode} to use for entities
* loaded during execution of the query.
* @since 4.0
*/
ManagedEntityMode managedEntityMode() default ManagedEntityMode.READ_WRITE;

/**
* (Optional) Query properties and hints. May include
* vendor-specific query hints.
Expand Down
16 changes: 16 additions & 0 deletions api/src/main/java/jakarta/persistence/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,22 @@ Query setParameter(int position, Date value,
*/
Integer getTimeout();

/**
* Set the {@link ManagedEntityMode} to be used for entities
* loaded during execution of this query.
*
* @since 4.0
*/
Query setManagedEntityMode(ManagedEntityMode managedEntityMode);

/**
* The {@link ManagedEntityMode} that will be in effect during
* execution of this query.
*
* @since 4.0
*/
ManagedEntityMode getManagedEntityMode();

/**
* Return an object of the specified type to allow access to
* a provider-specific API. If the provider implementation of
Expand Down
8 changes: 8 additions & 0 deletions api/src/main/java/jakarta/persistence/TypedQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,12 @@ TypedQuery<X> setParameter(int position, Date value,
* @since 3.2
*/
TypedQuery<X> setTimeout(Integer timeout);

/**
* Set the {@link ManagedEntityMode} to be used for entities
* loaded during execution of this query.
*
* @since 4.0
*/
TypedQuery<X> setManagedEntityMode(ManagedEntityMode managedEntityMode);
}
27 changes: 25 additions & 2 deletions spec/src/main/asciidoc/ch03-entity-operations.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,26 @@ After an entity has been removed, its state
(except for generated state) will be that of the entity at the point at
which the remove operation was called.

==== Read-only entities

The enumeration `ManagedEntityMode` allows an entity loaded into the
persistence context via a call to `find()` or via execution of a query
to be loaded in one of two modes.

[source,java]
----
include::../../../../api/src/main/java/jakarta/persistence/ManagedEntityMode.java[lines=18..-1]
----

By default, an entity is loaded in modifiable mode, and its state is
synchronized to the database when a flush operation occurs. An entity
may be loaded in read-only mode by passing `READ_ONLY` to
`EntityManager.find()` or `Query.setManagedEntityMode()`. Furthermore,
the current mode for a given managed entity may be changed by calling
`EntityManager.setManagedEntityMode()`. Changes made to an entity instance
currently loaded in read-only mode are not synchronized to the database,
and do not become persistent.

==== Synchronization to the Database [[a1955]]

In general, a persistence context will be
Expand Down Expand Up @@ -299,8 +319,8 @@ transaction, the persistence provider must not flush to the database.
The semantics of the flush operation, applied
to an entity X are as follows:

* If X is a managed entity, it is synchronized
to the database.
* If X is a managed entity, and it was loaded with
`ManagedEntityMode.READ_WRITE`, it is synchronized to the database.
** For all entities Y referenced by a
relationship from X, if the relationship to Y has been annotated with
the `cascade` element value `cascade=PERSIST` or `cascade=ALL`, the
Expand All @@ -315,6 +335,9 @@ transaction marked for rollback) or the transaction commit will fail.
the ownership of the relationship. If X owns the relationship, any
changes to the relationship are synchronized with the database;
otherwise, if Y owns the relationships, the behavior is undefined.
* If X is a managed entity, and it was loaded with
`ManagedEntityMode.READ_ONLY`, it is ignored by the flush operation,
and is not synchronized with the database.
* If X is a removed entity, it is removed from
the database. No `cascade` options are relevant.

Expand Down

0 comments on commit 8ddac32

Please sign in to comment.