forked from eclipse-ee4j/eclipselink
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jakartaee/persistence#454 - introduce FindOption interface and new ov…
…erloads of EM.find() * implemented public <T> T find(Class<T> entityClass, Object primaryKey, FindOption... options) * added FindOption processing for JPA API enums, Timeout class was not added yet Signed-off-by: Tomáš Kraus <[email protected]>
- Loading branch information
1 parent
6d8faa1
commit 47b8a90
Showing
5 changed files
with
210 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
...e.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/FindOptionUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* Copyright (c) 2023 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: | ||
// 08/31/2023: Tomas Kraus | ||
// - New Jakarta Persistence 3.2 Features | ||
package org.eclipse.persistence.internal.jpa; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.BiConsumer; | ||
|
||
import jakarta.persistence.CacheRetrieveMode; | ||
import jakarta.persistence.CacheStoreMode; | ||
import jakarta.persistence.FindOption; | ||
import jakarta.persistence.LockModeType; | ||
import jakarta.persistence.PessimisticLockScope; | ||
import jakarta.persistence.Timeout; | ||
import org.eclipse.persistence.config.QueryHints; | ||
|
||
/** | ||
* {@link FindOption} processing tools. | ||
* <p>Currently supported implementations:<ul> | ||
* <li>{@link LockModeType}</li> | ||
* <li>{@link CacheRetrieveMode}</li> | ||
* <li>{@link CacheStoreMode}</li> | ||
* <li>{@link PessimisticLockScope}</li> | ||
* <li>{@link Timeout}</li> | ||
* </ul> | ||
*/ | ||
class FindOptionUtils { | ||
|
||
/** | ||
* Parsed {@link FindOption} array. | ||
*/ | ||
record Options (LockModeType lockModeType, Map<String, Object> properties) { | ||
} | ||
|
||
// TODO-API-3.2 - FindOption not defined in EclipseLink scope, just in API. | ||
private static final class OptionsBuilder { | ||
|
||
private static final Map<Class<? extends FindOption>, BiConsumer<OptionsBuilder, FindOption>> ACTIONS = initActions(); | ||
// Tune this value to be at least number of supported FindOption classes. | ||
private static final int MAP_CAPACITY = 8; | ||
|
||
private final Map<String, Object> properties; | ||
private LockModeType lockModeType; | ||
|
||
// FindOption is mostly implemented by enums so Map based dispatcher may be faster than if statements with instanceof. | ||
private static Map<Class<? extends FindOption>, BiConsumer<OptionsBuilder, FindOption>> initActions() { | ||
Map<Class<? extends FindOption>, BiConsumer<OptionsBuilder, FindOption>> actions = new HashMap<>(MAP_CAPACITY); | ||
actions.put(LockModeType.class, OptionsBuilder::lockModeType); | ||
actions.put(CacheRetrieveMode.class, OptionsBuilder::cacheRetrieveMode); | ||
actions.put(CacheStoreMode.class, OptionsBuilder::cacheStoreMode); | ||
actions.put(PessimisticLockScope.class, OptionsBuilder::pessimisticLockScope); | ||
actions.put(Timeout.class, OptionsBuilder::timeout); | ||
return actions; | ||
} | ||
|
||
private OptionsBuilder(Map<String, Object> properties) { | ||
this.lockModeType = null; | ||
if (properties != null) { | ||
this.properties = new HashMap<>(properties.size() + MAP_CAPACITY); | ||
this.properties.putAll(properties); | ||
} else { | ||
this.properties = new HashMap<>(MAP_CAPACITY); | ||
} | ||
} | ||
|
||
// Dispatch rules Map is in static content so all handlers must be static. | ||
private static void lockModeType(OptionsBuilder builder, FindOption lockModeType) { | ||
builder.lockModeType = (LockModeType) lockModeType; | ||
} | ||
|
||
private static void cacheRetrieveMode(OptionsBuilder builder, FindOption cacheRetrieveMode) { | ||
builder.properties.put(QueryHints.CACHE_RETRIEVE_MODE, cacheRetrieveMode); | ||
} | ||
|
||
private static void cacheStoreMode(OptionsBuilder builder, FindOption cacheStoreMode) { | ||
builder.properties.put(QueryHints.CACHE_STORE_MODE, cacheStoreMode); | ||
} | ||
|
||
private static void pessimisticLockScope(OptionsBuilder builder, FindOption cacheStoreMode) { | ||
builder.properties.put(QueryHints.PESSIMISTIC_LOCK_SCOPE, cacheStoreMode); | ||
} | ||
|
||
private static void timeout(OptionsBuilder builder, FindOption timeout) { | ||
builder.properties.put(QueryHints.QUERY_TIMEOUT, timeout); | ||
} | ||
|
||
private static Options build(Map<String, Object> properties, FindOption... options) { | ||
OptionsBuilder builder = new OptionsBuilder(properties); | ||
for (FindOption option : options) { | ||
// TODO: Java 21 will allow pattern matching for switch, e.g. case rules for individual types. | ||
// Fast dispatch for known classes. | ||
BiConsumer<OptionsBuilder, FindOption> action = ACTIONS.get(option.getClass()); | ||
if (action != null) { | ||
action.accept(builder, option); | ||
// Fallback dispatch for unknown classes that may still match rules. | ||
// No need to handle enums because they can't be extended. | ||
} else if (option instanceof Timeout) { | ||
timeout(builder, option); | ||
} else { | ||
// TODO: Log unknown FindOption instance | ||
} | ||
} | ||
// Parsed options shall be completely immutable. | ||
return new Options(builder.lockModeType, Collections.unmodifiableMap(builder.properties)); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Parse provided {@link FindOption} array. | ||
* | ||
* @param options {@link FindOption} array | ||
* @return {@link Options} instance with parsed array content | ||
*/ | ||
static Options parse(FindOption... options) { | ||
return OptionsBuilder.build(null, options); | ||
} | ||
|
||
/** | ||
* Parse provided {@link FindOption} array. | ||
* Returned {@link Options} instance contains provided {@code properties} which | ||
* may be overwritten by content of {@link FindOption} array. | ||
* | ||
* @param properties initial query properties | ||
* @param options {@link FindOption} array | ||
* @return {@link Options} instance with parsed array content | ||
*/ | ||
static Options parse(Map<String, Object> properties, FindOption... options) { | ||
return OptionsBuilder.build(properties, options); | ||
} | ||
|
||
} |
48 changes: 48 additions & 0 deletions
48
...rsistence.jpa/src/test/java/org/eclipse/persistence/internal/jpa/FindOptionUtilsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2023 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: | ||
// 08/31/2023: Tomas Kraus | ||
// - New Jakarta Persistence 3.2 Features | ||
package org.eclipse.persistence.internal.jpa; | ||
|
||
import jakarta.persistence.CacheRetrieveMode; | ||
import jakarta.persistence.CacheStoreMode; | ||
import jakarta.persistence.LockModeType; | ||
import jakarta.persistence.PessimisticLockScope; | ||
import junit.framework.TestCase; | ||
import org.eclipse.persistence.config.QueryHints; | ||
|
||
/** | ||
* | ||
*/ | ||
public class FindOptionUtilsTest extends TestCase { | ||
|
||
public void testParseAllOptions() { | ||
FindOptionUtils.Options parsed = FindOptionUtils.parse( | ||
LockModeType.OPTIMISTIC, | ||
CacheRetrieveMode.USE, | ||
CacheStoreMode.REFRESH, | ||
PessimisticLockScope.EXTENDED); | ||
assertEquals(parsed.lockModeType(), LockModeType.OPTIMISTIC); | ||
assertEquals(parsed.properties().get(QueryHints.CACHE_RETRIEVE_MODE), CacheRetrieveMode.USE); | ||
assertEquals(parsed.properties().get(QueryHints.CACHE_STORE_MODE), CacheStoreMode.REFRESH); | ||
assertEquals(parsed.properties().get(QueryHints.PESSIMISTIC_LOCK_SCOPE), PessimisticLockScope.EXTENDED); | ||
} | ||
|
||
/* TODO-API-3.2: Add Timeout tests when API is fixed | ||
private static final class CustomTimeout extends Timeout { | ||
} | ||
*/ | ||
|
||
} |