= JdoSupportService
:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Primarily provides access to the current thread's _PersistenceManagerFactory_ and hence also the current thread's _PersistenceManager_ .

== API

[source,java]
.JdoSupportService.java
----
interface JdoSupportService {
  PersistenceManagerFactory getPersistenceManagerFactory()
  T refresh(T domainObject)     // <.>
  void ensureLoaded(Collection<?> collectionOfDomainObjects)
  List<Map<String, Object>> executeSql(String sql)
  Integer executeUpdate(String sql)
  void deleteAll(Class<?>... pcClasses)     // <.>
  List<T> executeQuery(Class<T> cls, BooleanExpression filter)     // <.>
  List<T> executeQuery(Class<T> cls)
  T executeQueryUnique(Class<T> cls, BooleanExpression filter)     // <.>
  T executeQueryUnique(Class<T> cls)
  JDOQLTypedQuery<T> newTypesafeQuery(Class<T> cls)     // <.>
  void disableMultivaluedFetch(JDOQLTypedQuery<?> query)     // <.>
  void disableMultivaluedFetch(Query<?> query)     // <.>
  PersistenceManager getPersistenceManager()
}
----

<.> xref:#refresh_T[refresh(T)]
+
--
Force a reload (corresponding to the JDO `PersistenceManager` 's `refresh()` method) of a domain objects.
--
<.> xref:#deleteAll_Class[deleteAll(Class)]
+
--
Force the deletion of all instances of the specified class.
--
<.> xref:#executeQuery_Class_BooleanExpression[executeQuery(Class, BooleanExpression)]
+
--
To perform the most common use-case of executing a (type-safe) query against the specified class, filtering using the provided _BooleanExpression_ , then automatically cloning the returned list and closing the query.
--
<.> xref:#executeQueryUnique_Class_BooleanExpression[executeQueryUnique(Class, BooleanExpression)]
+
--
To perform a common use-case of executing a (type-safe) query against the specified class, filtering a unique match using the provided _BooleanExpression_ , then returning the result and closing the query.
--
<.> xref:#newTypesafeQuery_Class[newTypesafeQuery(Class)]
+
--
To support the execution of type-safe queries using DataNucleus' lower-level APIs (eg for group by and so on).
--
<.> xref:#disableMultivaluedFetch_JDOQLTypedQuery[disableMultivaluedFetch(JDOQLTypedQuery)]
+
--
Fetch Optimization
--
<.> xref:#disableMultivaluedFetch_Query[disableMultivaluedFetch(Query)]
+
--
Fetch Optimization
--

== Members

[#refresh_T]
=== refresh(T)

Force a reload (corresponding to the JDO `PersistenceManager` 's `refresh()` method) of a domain objects.

In fact, this may just reset the lazy-load state of the domain object, but the effect is the same: to cause the object's state to be reloaded from the database.

The particular example that led to this method being added was a 1:m bidirectional relationship, analogous to `Customer <-> * Order` . Persisting the child `Order` object did not cause the parent `Customer` 's collection of orders to be updated. In fact, JDO does not make any such guarantee to do so. Options are therefore either to maintain the collection in code, or to refresh the parent.

[#deleteAll_Class]
=== deleteAll(Class)

Force the deletion of all instances of the specified class.

Note: this is intended primarily for testing purposes, eg clearing existing data as part of installing fixtures. It will generate a `SQL DELETE` for each instance. To perform a bulk deletion with a single `SQL DELETE` , use _#executeUpdate(String)_ .

Implementation note: It can occasionally be the case that Isis' internal adapter for the domain object is still in memory. JDO/DataNucleus seems to bump up the version of the object prior to its deletion, which under normal circumstances would cause Isis to throw a concurrency exception. Therefore To prevent this from happening (ie to _force_ the deletion of all instances), concurrency checking is temporarily disabled while this method is performed.

[#executeQuery_Class_BooleanExpression]
=== executeQuery(Class, BooleanExpression)

To perform the most common use-case of executing a (type-safe) query against the specified class, filtering using the provided _BooleanExpression_ , then automatically cloning the returned list and closing the query.

Typical usage:

----

         final QToDoItem q = QToDoItem.candidate();
         return executeQuery(ToDoItem.class,
                             q.atPath.eq(atPath).and(
                             q.description.indexOf(description).gt(0))
                             );
    
----

[#executeQueryUnique_Class_BooleanExpression]
=== executeQueryUnique(Class, BooleanExpression)

To perform a common use-case of executing a (type-safe) query against the specified class, filtering a unique match using the provided _BooleanExpression_ , then returning the result and closing the query.

Typical usage:

----

         final QToDoItem q = QToDoItem.candidate();
         return executeQueryUnique(ToDoItem.class,
                             q.atPath.eq(atPath).and(
                             q.description.eq(description))
                             );
    
----

[#newTypesafeQuery_Class]
=== newTypesafeQuery(Class)

To support the execution of type-safe queries using DataNucleus' lower-level APIs (eg for group by and so on).

Responsibility for cloning any result sets and closing the query is the responsibility of the caller.

[#disableMultivaluedFetch_JDOQLTypedQuery]
=== disableMultivaluedFetch(JDOQLTypedQuery)

Fetch Optimization

FromDN-5.2...

For RDBMS any single-valued member will be fetched in the original SQL query, but with multiple-valued members this is not supported. However what will happen is that any collection/array field will be retrieved in a single SQL query for all candidate objects (by default using an EXISTS subquery); this avoids the "N+1" problem, resulting in 1 original SQL query plus 1 SQL query per collection member. Note that you can disable this by either not putting multi-valued fields in the FetchPlan, or by setting the query extension datanucleus.rdbms.query.multivaluedFetch to none (default is "exists" using the single SQL per field).

[#disableMultivaluedFetch_Query]
=== disableMultivaluedFetch(Query)

Fetch Optimization

include::hooks/JdoSupportService_010-examples-and-usage.adoc[]
