Skip to content
Closed
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
31 changes: 31 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/IncludeRemovals.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;


import jakarta.persistence.EntityGraph;
import jakarta.persistence.FindOption;

import java.util.List;

/**
* MultiFindOption implementation to specify whether the returned list
* of entity instances should contain instances that have been
* {@linkplain Session#remove(Object) marked for removal} in the
* current session, but not yet deleted in the database.
* <p>
* The default is {@link #EXCLUDE}, meaning that instances marked for
* removal are replaced by null in the returned list of entities when {@link OrderedReturn}
* is used.
*
* @see org.hibernate.MultiFindOption
* @see OrderedReturn
* @see org.hibernate.Session#findMultiple(Class, List, FindOption...)
* @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
*/
public enum IncludeRemovals implements MultiFindOption {
INCLUDE,
EXCLUDE
}
14 changes: 14 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/MultiFindOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;


import jakarta.persistence.FindOption;

/**
* Simple marker interface for FindOptions which can be applied to multiple id loading.
*/
public interface MultiFindOption extends FindOption {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more thing, since MultiFindOption:

  • doesn't actually add any type safety (it extends MultiFindOption)
  • has a quite ugly name
  • can be added into the hierarchy at any time if needed

I would just remove it, and make these new options implement FindOption directly.

It's not adding anything.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was steve's suggestion to do it like this.
It does make the restriction in session.find(..., FindOption ... options) somewhat cleaner having it around

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does make the restriction in session.find(..., FindOption ... options) somewhat cleaner having it around

I don't know what you mean by this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private <T> void setLoadAccessOptions(FindOption[] options, IdentifierLoadAccessImpl<T> loadAccess) {
    for ( FindOption option : options ) {
        if ( option instance of MultiFindOption ) {
            throw ...
        }
    }
}

is quite nicer than individually checking for each type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not adding anything.

I disagree. Find usages of MultiFindOption has value.

has a quite ugly name

Your opinion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is quite nicer than individually checking for each type.

Which is what I meant

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if you really insist on retaining it (I would not, since this is the root package org.hibernate) then how about FindMultipleOption, to reflect that it is an option for the findMultiple() method?

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
* @see Session#byMultipleIds(Class)
*
* @author Steve Ebersole

* @deprecated Use forms of {@linkplain Session#findMultiple} accepting
* {@linkplain jakarta.persistence.FindOption} instead of {@linkplain Session#byMultipleIds}.
*/
@Deprecated(since = "7.2", forRemoval = true)
public interface MultiIdentifierLoadAccess<T> {

/**
Expand Down
32 changes: 32 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/OrderedReturn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;


import jakarta.persistence.EntityGraph;
import jakarta.persistence.FindOption;

import java.util.List;

/**
* MultiFindOption implementation to specify whether the returned list
* of entity instances should be ordered, where the position of an entity
* instance is determined by the position of its identifier
* in the list of ids passed to {@code findMultiple(...)}.
* <p>
* The default is {@link #ORDERED}, meaning the positions of the entities
* in the returned list correspond to the positions of their ids. In this case,
* the {@link IncludeRemovals} handling of entities marked for removal
* becomes important.
*
* @see org.hibernate.MultiFindOption
* @see IncludeRemovals
* @see org.hibernate.Session#findMultiple(Class, List, FindOption...)
* @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
*/
public enum OrderedReturn implements MultiFindOption {
ORDERED,
UNORDERED
}
10 changes: 10 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,12 @@ public interface Session extends SharedSessionContract, EntityManager {
* @throws HibernateException If the given class does not resolve as a mapped entity
*
* @see #findMultiple(Class, List, FindOption...)
*
* @deprecated This method will be removed.
* Use {@link #findMultiple(Class, List, FindOption...)} instead.
* See {@link MultiFindOption}.
*/
@Deprecated(since = "7.2", forRemoval = true)
<T> MultiIdentifierLoadAccess<T> byMultipleIds(Class<T> entityClass);

/**
Expand All @@ -1177,7 +1182,12 @@ public interface Session extends SharedSessionContract, EntityManager {
* @return an instance of {@link MultiIdentifierLoadAccess} for executing the lookup
*
* @throws HibernateException If the given name does not resolve to a mapped entity
*
* @deprecated This method will be removed.
* Use {@link #findMultiple(Class, List, FindOption...)} instead.
* See {@link MultiFindOption}.
*/
@Deprecated(since = "7.2", forRemoval = true)
<T> MultiIdentifierLoadAccess<T> byMultipleIds(String entityName);

/**
Expand Down
30 changes: 30 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/SessionChecking.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate;


import jakarta.persistence.EntityGraph;
import jakarta.persistence.FindOption;

import java.util.List;

/**
* MultiFindOption implementation to specify whether the ids of managed entity instances already
* cached in the current persistence context should be excluded.
* from the list of ids sent to the database.
* <p>
* The default is {@link #DISABLED}, meaning all ids are included and sent to the database.
*
* Use {@link #ENABLED} to exclude already managed entity instance ids from
* the list of ids sent to the database.
*
* @see org.hibernate.MultiFindOption
* @see org.hibernate.Session#findMultiple(Class, List , FindOption...)
* @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
*/
public enum SessionChecking implements MultiFindOption {
ENABLED,
DISABLED
}
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,15 @@ else if ( option instanceof ReadOnlyMode ) {
else if ( option instanceof BatchSize batchSizeOption ) {
batchSize = batchSizeOption.batchSize();
}
else if ( option instanceof SessionChecking sessionChecking ) {
loadAccess.enableSessionCheck( option == sessionChecking.ENABLED );
}
else if ( option instanceof OrderedReturn orderedReturn ) {
loadAccess.enableOrderedReturn( option == orderedReturn.ORDERED );
}
else if ( option instanceof IncludeRemovals includeRemovals ) {
loadAccess.enableReturnOfDeletedEntities( option == includeRemovals.INCLUDE );
}
}
loadAccess.with( lockOptions )
.with( interpretCacheMode( storeMode, retrieveMode ) )
Expand Down Expand Up @@ -2291,6 +2300,9 @@ else if ( option instanceof EnabledFetchProfile enabledFetchProfile ) {
else if ( option instanceof ReadOnlyMode ) {
loadAccess.withReadOnly( option == ReadOnlyMode.READ_ONLY );
}
else if ( option instanceof MultiFindOption multiFindOption ) {
throw new IllegalArgumentException( "Option '" + multiFindOption + "' can only be used in 'findMultiple()'" );
}
}
if ( lockOptions.getLockMode().isPessimistic() ) {
if ( lockOptions.getTimeOut() == WAIT_FOREVER_MILLI ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
*/
package org.hibernate.orm.test.dynamicmap;

import org.hibernate.IncludeRemovals;
import org.hibernate.OrderedReturn;
import org.hibernate.ReadOnlyMode;
import org.hibernate.SessionChecking;
import org.hibernate.graph.RootGraph;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
Expand All @@ -17,6 +20,7 @@
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* @author Steve Ebersole
Expand Down Expand Up @@ -58,6 +62,15 @@ void testFindWithOptions(SessionFactoryScope factoryScope) {
} );
}

@Test
void testFindWithIllegalOptions(SessionFactoryScope factoryScope) {
factoryScope.inTransaction( (session) -> {
assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, SessionChecking.ENABLED ) );
assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, OrderedReturn.ORDERED ) );
assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, IncludeRemovals.INCLUDE ) );
} );
}

@Test
void testFindWithGraph(SessionFactoryScope factoryScope) {
factoryScope.inTransaction( (session) -> {
Expand Down
Loading