Migration Considerations
-
-
- OpenJPA 2.0.0
-
-
-
- Incompatibilities
-
-
+
+ OpenJPA 4.2.0
+
+ Incompatibilities
+
- The following sections indicate changes that are incompatible
- between OpenJPA 1.x.x releases and the 2.0 release. Some may
- require application changes. Others can be remedied through the
- use of compatibility options. If your application uses a
- version 1.0 persistence.xml, compatibility options will be set
- appropriately to maintain backward compatibility. OpenJPA 2.0
- applications using a version 2.0 persistence.xml and requiring
- OpenJPA 1.x.x compatibility may need to configure the
- appropriate compatibility options to get the desired behavior.
+ OpenJPA 4.2.0 implements the Jakarta Persistence 3.2 specification and passes the
+ Jakarta Persistence 3.2 TCK. The following sections indicate changes that are incompatible
+ between OpenJPA 4.1.x releases and the 4.2.0 release. Most of them align OpenJPA with
+ the specification and cannot be switched off; where a configuration option restores
+ the previous behavior, it is mentioned in the respective section. Open follow-up items
+ from the review of this work are tracked under OPENJPA-2945.
-
-
- getProperties()
-
-
+
+ Platform and Dependency Requirements
- The OpenJPAEntityManagerFactory interface getProperties()
- method was changed to return a Map instead of a
- Properties object. This change was made in order to
- support the getProperties() method defined in the
- JPA 2.0 specification.
+ OpenJPA 4.2.0 requires Java 17 or later at build and run time (4.1.x required
+ Java 11). All jars contain Java 17 class files. Java 21 and Java 25 runtimes are
+ supported; class files of newer JDKs are read through
+ xbean-asm9-shaded 4.30.
-
-
-
- Detach Behavior
-
-
- The detach behavior has changed in several ways:
-
-
-
- In the 1.x.x release, managed entities
- were flushed to the database as part of the
- detach operation. This is no longer done in
- 2.0.
-
-
-
-
- In the 1.x.x release, entities were copied
- and returned. In 2.0, for those methods
- that have return values, the original
- entities are returned.
-
-
-
-
- In the 1.x.x release, managed entities still
- exist in the persistent context. In 2.0,
- they are removed.
-
-
-
-
- In the 1.x.x release, the detach operation
- is recursively cascaded to all referenced
- entities. In 2.0, the detach operation is
- only cascaded to those entities for which
- Cascade=detach has been specified.
-
-
-
+ The jakarta.persistence:jakarta.persistence-api dependency was
+ raised from 3.1.0 to 3.2.0 (Jakarta EE 11 level). Applications must update explicit
+ dependencies on the API and recompile. Custom wrappers implementing
+ jakarta.persistence interfaces (EntityManager,
+ EntityManagerFactory, Query,
+ CriteriaBuilder, PersistenceUnitInfo, ...)
+ must implement the new 3.2 methods. The persistence_3_2.xsd and
+ orm_3_2.xsd schemas are bundled and selected for documents
+ declaring version="3.2"; version="3.1"
+ documents are still not accepted (use 3.0 or 3.2).
- Applications that use a 1.0 persistence.xml will
- automatically maintain OpenJPA 1.x.x behavior. It is
- possible for a version 2.0 application to revert back to
- the 1.x.x behavior for some of these items by setting the
- openjpa.Compatibility property as follows:
-
- CopyOnDetach=true
- FlushBeforeDetach=true
- CascadeWithDetach=true
-
+ XML column mapping (XMLValueHandler) and the detection of
+ XML-mapped value classes now use jakarta.xml.bind (JAXB 4)
+ instead of javax.xml.bind (JAXB 2). The optional dependencies
+ are jakarta.xml.bind:jakarta.xml.bind-api 4.0.x and a JAXB 4
+ runtime such as com.sun.xml.bind:jaxb-impl 4.0.x. Value classes
+ that are still annotated with javax.xml.bind.annotation
+ annotations are no longer recognized as XML column types and silently fall back to
+ the default (serialized) mapping. Migrate such classes to
+ jakarta.xml.bind.annotation.
- In addition, a new method has been provided on the
-
- OpenJPAEntityManager
- interface to return a copy of the entity:
-
- public <T> T detachCopy(T pc):
-
+ The managed JDBC driver versions used for testing were raised: MySQL Connector/J 9.x
+ (com.mysql:mysql-connector-j, driver class
+ com.mysql.cj.jdbc.Driver), MariaDB Connector/J 3.5.x, Microsoft
+ mssql-jdbc 13.x and Derby 10.16.x (which itself requires Java 17).
+ MySQLDictionary now also recognises
+ com.mysql.cj.jdbc.exceptions.MySQLTimeoutException as a timeout
+ exception, so lock and query timeouts are classified correctly with Connector/J 8
+ and later. Drivers are not shipped with OpenJPA; see
+ for the tested database and driver versions.
+
+
+ Build-only changes: the Maven profile test-h2-2 was removed
+ (use test-h2), and the legacy JPA 1.0 / 2.0 TCK profiles in
+ openjpa-integration/tck were replaced by the Jakarta Persistence
+ 3.2 TCK runner (-Ptck32-profile, run-tck32.sh).
-
-
- Use of private persistent properties
-
-
+
+ SecurityManager Support Removed
- In 1.x.x releases of OpenJPA, if property access was used,
- private properties were considered persistent. This is
- contrary to the JPA specification, which states that
- persistent properties must be public or protected. In
- OpenJPA 2.0 and later, private properties will not be
- persistent by default.
+ All AccessController.doPrivileged(...) calls were removed from
+ OpenJPA. Running OpenJPA under a Java SecurityManager with a
+ policy that grants permissions only to the OpenJPA jars is no longer supported (the
+ SecurityManager is deprecated for removal since Java 17 and
+ permanently disabled since Java 24, JEP 486).
- Applications that use a 1.0 persistence.xml will
- automatically maintain OpenJPA 1.x.x behavior. It is
- possible for a version 2.0 application to revert back to
- the 1.x.x behavior by setting the value of the
- openjpa.Compatibility
- property PrivatePersistentProperties to
- true. If compile time enhancement is
- used, this property must be specified at the time of
- enhancement and at runtime.
+ As a consequence the public PrivilegedAction factory methods of
+ org.apache.openjpa.lib.util.J2DoPrivHelper (for example
+ getForNameAction, getClassLoaderAction,
+ newInstanceAction, getContextClassLoaderAction)
+ were removed; only getLineSeparator(),
+ getPathSeparator(), newInstance(Class) and
+ newDeamonThread(Runnable, String) remain. Third-party code
+ (custom product derivations, dictionaries, plugins, application server integrations)
+ using these helpers must call the JDK API directly. Plugin classes instantiated
+ through J2DoPrivHelper.newInstance may now have a non-public
+ no-argument constructor.
-
-
- Query.setParameter()
-
-
+
+ New JPQL Reserved Identifiers
- The Query interface setParameter() method behavior has
- changed to throw an IllegalArgumentException (as required
- by the JPA specification) if more parameter substitutions
- are supplied than defined in the createQuery(),
- createNamedQuery(), or createNativeQuery() invocation.
- OpenJPA 1.2.x and prior versions silently ignored these
- extraneous parameter substitutions and allowed the Query
- to be processed.
+ The JPQL grammar now knows the Jakarta Persistence 3.2 keywords
+ ID, VERSION, FIRST,
+ LAST, ON, NULLS,
+ CAST, STRING, INTEGER,
+ LONG, FLOAT, DOUBLE,
+ TREAT, UNION, INTERSECT,
+ EXCEPT, RIGHT and REPLACE
+ (case-insensitive), as well as the || concatenation operator.
+ In previous releases these words could be used as identification variables and
+ result aliases, for example SELECT e.id AS id FROM E e ORDER BY id
+ or SELECT first FROM Foo first. Such queries are now rejected
+ with a parse error, as required by section 4.4.1 of the specification.
-
-
-
- Serialization of Entities
-
-
- In 1.x.x releases of OpenJPA, when an entity was serialized
- after calling EntityManager.find(), detach() or detachAll()
- then all
- references were removed as expected, but when the same
- entity instance was serialized after calling
- EntityManager.clear() the proxy classes were not removed.
+ With the exception of INTEGER, LONG,
+ FLOAT and DOUBLE the new keywords may still be
+ used as path components, so attributes named id,
+ version, first or replace
+ can still be navigated (o.version). Attributes named
+ integer, long, float or
+ double can no longer be referenced in a JPQL path expression;
+ rename them or access them through the Criteria API or native SQL. Rename
+ identification variables and aliases that collide with the new keywords (most
+ commonly id, version, first,
+ last and on). There is no soft-keyword mode
+ and no compatibility option.
+
+
+ JPQL Integer Literals are typed Integer
- This has two side-effects:
- when entities are remoted across JVM boundaries (RPC)
- or deserialized the OpenJPA runtime must be available
- on the classpath (both client and server containers);
- when entities are deserialized the OpenJPA runtime must
- be the exact same revision as used to serialize the
- entities due to the proxy classes using dynamically
- generated serialVersionUID values.
+ Previous releases always created JPQL integer literals as
+ java.lang.Long, so SELECT 1 FROM ... or
+ e.intField + 1 produced Long results.
+ As required by section 4.8.5 of the specification, an integer literal without an
+ l/L suffix that fits into the
+ int range is now a java.lang.Integer;
+ arithmetic on Byte, Short and
+ Integer operands is promoted to Integer
+ (also in the Criteria API).
- Starting with OpenJPA 2.0, this behavior has been
- modified, so that by default all proxies will be removed
- during serialization. See
-
- on how the behavior changes based on the
- DetachedStateField setting along with
-
- for more details on how to override the default
- DetachedStateField setting.
+ Application code that casts such results to Long must be
+ adapted to Integer or Number, or use an
+ explicit 1L literal. No compatibility option exists.
+
+
+ Query value conversion
- Applications that use a 1.0 persistence.xml will
- automatically maintain the old behavior. It is
- possible for a version 2.0 application to revert back to
- the prior 1.x.x behavior by setting the following
- openjpa.Compatibility property as follows:
-
- IgnoreDetachedStateFieldForProxySerialization=true
-
+ A String literal compared with a numeric path or parameter
+ (WHERE e.intField = '1', cb.equal(path, "12"))
+ is now parsed as a number of the path's type; previously a one-character literal was
+ compared as a Character and longer literals were rejected. The
+ character comparison is only used when the literal cannot be parsed as a number.
+ Selecting a collection- or map-valued attribute (SELECT e.addresses FROM
+ Employee e, query.select(root.get("addresses"))) is
+ treated as an implicit join and returns one row per element, typed as the element
+ type, instead of a collection-typed projection.
+ java.sql.Date values are no longer implicitly converted to
+ java.sql.Time or java.sql.Timestamp
+ when query values are compared (the same rule already applied to
+ java.util.Date). Enum names read from padded
+ CHAR columns are trimmed before Enum.valueOf().
+ No compatibility option exists.
-
-
- openjpa.jdbc.QuerySQLCache
-
-
+
+ Query.getResultList() returns a materialized ArrayList
- In prior 1.x.x releases, the openjpa.jdbc.QuerySQLCache
- configuration property for Prepared SQL Cache accepted
- value all to never drop items from the
- cache, but this option is no longer supported and will cause
- a PersistenceException with a root cause of a ParseException
- to be thrown. See
-
- for details on the available configuration values.
+ Query.getResultList() previously returned a lazy
+ org.apache.openjpa.lib.rop.ResultList wrapper that streamed
+ rows on demand (see ) and became invalid
+ when the query or the EntityManager was closed. Jakarta
+ Persistence 3.2 requires a mutable List, so the result is now
+ copied into a java.util.ArrayList: all rows are fetched
+ immediately, the list stays usable after the EntityManager
+ is closed, and it is no longer an instance of ResultList.
+ Query.getResultStream() also materializes the complete result
+ first. Large result set collections on entity fields
+ () are not affected.
+
+
+ For very large query results use setFirstResult() /
+ setMaxResults() paging, or obtain the kernel query via
+ OpenJPAQuery.getDelegate() for lazy semantics. Code that casts
+ the result to ResultList or
+ DelegatingResultList must be changed.
-
-
-
- Disabling AutoOff Collection Tracking
-
-
-
- The default behavior of OpenJPA in tracking collections is that
- if the number of modifications to the collection exceeds the
- current number of elements in collection then OpenJPA will
- disable tracking the collections. OpenJPA 2.0 added a compatibility
- property to disable turning off the collection tracking.
-
-
- The behavior of Auto disabling of collection tracking can be
- avoided by setting the value of the
- openjpa.Compatibility property
- autoOff to false.
- The default behavior of auto disabling the collection tracking
- is not changed. But when the above property is set then the
- collection tracking will not be disabled automatically.
-
-
-
-
- Internal Behavioral Differences
-
-
- The following sections indicate internal changes between
- OpenJPA 1.x.x releases and the 2.0 release. As these are
- internal implementation specific behaviors not covered by
- the JPA specification, no changes should be required for
- applications that did not use or depend upon OpenJPA specific
- APIs or behavior.
-
-
-
-
- PreUpdate/PostUpdate Life Cycle Callbacks
-
-
+
+ Bulk DELETE no longer cascades
- If an entity was updated between the persist()
- and commit() operations in OpenJPA 1.x, then
- any PreUpdate and PostUpdate life cycle callback
- methods would be executed. Starting in OpenJPA
- 1.3 and 2.0, these callbacks will not get executed.
+ In previous releases a JPQL or Criteria bulk DELETE against an
+ entity with cascade-delete or dependent relations (for example
+ @OneToMany(cascade=REMOVE) or an
+ @ElementCollection) was executed in memory: every instance was
+ loaded and removed through the persistence context, cascading to related entities
+ and cleaning up join table and element collection rows. As required by section
+ 4.10 of the specification, bulk operations do not cascade. A DELETE
+ query now issues a single SQL DELETE against the entity table(s);
+ related entities, join table rows and element collection rows are left untouched
+ and will cause foreign key violations unless the database defines
+ ON DELETE CASCADE.
- The JPA 2.0 specification section on "Semantics
- of the Life Cycle Callback Methods for Entities"
- has been updated to include a Note that the
- callback behavior for updating an entity after
- the persist operation is implementation specific
- and should not be relied upon.
+ Delete dependents explicitly (separate bulk deletes or em.remove())
+ or rely on database-level cascades. Note that a bulk UPDATE or
+ DELETE that still has to be executed in memory now flushes all
+ pending changes of the persistence context after processing. No compatibility
+ option exists. See also .
-
-
- createEntityManagerFactory Exceptions
-
-
+
+ FlushModeType.AUTO flushes whenever the context is dirty
- The JPA 2.0 specification section on
- "Bootstrapping in Java SE Environments" states
- that persistence providers must return null
- if they are not a qualified provider for the
- given persistence unit.
+ Previously a query only flushed pending changes when a dirty instance belonged to
+ a type in the query's access path, and never for SELECT queries
+ when was true. With
+ FlushModeType.AUTO (the default,
+ =true) and an active
+ transaction, a query now flushes whenever any instance in the persistence context
+ is new, dirty or deleted, regardless of the query's access path, and overrides
+ openjpa.IgnoreChanges. Applications with write-heavy transactions
+ may observe more flushes (and therefore earlier constraint or trigger evaluation).
- However, OpenJPA may throw a RuntimeException
- if an error occurs while trying to create a
- qualified persistence unit, like for invalid
- openjpa.* specific configuration settings or
- for schema validation failures.
+ To restore the previous behavior use FlushModeType.COMMIT on
+ the query or the EntityManager, or set
+ openjpa.FlushBeforeQueries to false or
+ with-connection.
+
+
+ Exceptions mark the transaction rollback-only; closed EntityManager checks
- If the Apache Geronimo JPA 2.0 Spec APIs are
- used, then any exceptions returned by a
- persistence provider will be wrapped within
- a PersistenceException. When the JPA 2.0 API
- reference implementation is used, any
- RuntimeExceptions will be returned to the
- calling application without being wrapped.
- Other JPA 2.0 API and implementation providers
- or versions may behave differently.
+ As required by section 3.3.7.1 of the specification, every
+ RuntimeException raised by an EntityManager
+ or Query method now marks the active transaction for
+ rollback, except NoResultException,
+ NonUniqueResultException,
+ LockTimeoutException and
+ QueryTimeoutException. In previous releases the transaction
+ remained committable after, for example, an IllegalArgumentException
+ from find(), createNamedQuery() or an invalid
+ CriteriaQuery. Applications that caught such an exception and
+ committed the same transaction now receive a RollbackException
+ and must restart the transaction.
+
+
+ Operations on a closed EntityManager or its
+ Query objects now consistently throw
+ IllegalStateException. This includes
+ getEntityManagerFactory(), getCriteriaBuilder(),
+ getMetamodel(), getDelegate(),
+ setProperty(), isJoinedToTransaction(),
+ createEntityGraph(), createQuery(CriteriaQuery)
+ and Query.getHints(), getLockMode(),
+ closeAll() and the parameter accessors, which used to work on a
+ closed EntityManager. Further changes:
+ getLockMode()/setLockMode() on a bulk
+ UPDATE/DELETE query and
+ executeUpdate() on a SELECT query throw
+ IllegalStateException;
+ createQuery(CriteriaQuery) snapshots the criteria state, so
+ modifying the CriteriaQuery afterwards no longer affects the
+ created Query; isJoinedToTransaction()
+ returns true for an active resource-local transaction.
-
-
- openjpa.QueryCache default
-
-
+
+ Argument validation in find(), getReference(), detach(), contains(), remove()
- In previous releases, the default value for the
- openjpa.QueryCache property was true
- when the openjpa.DataCache was enabled. Depending on
- application characteristics, this default QueryCache
- enablement actually could negate much of the potential
- gains achieved by using the DataCache. Thus, the default
- value for the openjpa.QueryCache property is now
- false.
+ find(cls, null) previously returned null, a
+ primary key of the wrong type or a non-entity class surfaced later as an OpenJPA
+ ArgumentException or a failed lookup, and removing a detached
+ unenhanced entity could be silently ignored. These methods now validate their
+ arguments as required by the specification and throw
+ IllegalArgumentException (marking the transaction for
+ rollback) for null keys, non-entity classes, primary keys of an
+ incompatible type (numeric widening such as Integer to
+ Long is accepted, narrowing is rejected), non-entities
+ passed to detach()/contains(), and detached
+ instances passed to remove(). getReference()
+ throws EntityNotFoundException also for unenhanced entities.
- To re-enable the default QueryCache behavior, you need to
- include the following property in your persistence.xml
- configuration.
-
- <property name="openjpa.QueryCache" value="true"/>
-
+ Guard against null keys, pass keys of the declared
+ @Id type and merge() detached instances before
+ removing them. No compatibility option exists.
+
+
+ EntityManager.close() with an active resource-local transaction
- If your configuration had previously enabled the QueryCache
- explicitly, then you might have to include the
- true value into your configuration
- (if you relied on the previous default). Otherwise, your
- current QueryCache enablement will continue to work.
-
- <property name="openjpa.QueryCache" value="true(CacheSize=1000, SoftReferenceSize=100)"/>
-
+ Previously EntityManager.close() threw an
+ InvalidStateException while a resource-local transaction was
+ active; a deferred close existed only for managed (JTA) transactions with the
+ CloseOnManagedCommit compatibility flag. As required by sections
+ 3.3.2 and 7.7 of the specification, close() now always returns
+ and the persistence context is released when the transaction completes:
+ isOpen() reports false immediately while
+ em.getTransaction().commit()/rollback()
+ remain callable.
+
+
+ Code that relied on the exception to detect a leaked open transaction must check
+ em.getTransaction().isActive() itself and end the transaction
+ explicitly. There is no option to restore the exception.
-
-
-
-
- OpenJPA 2.2.0
-
-
- Incompatibilities
-
- The following sections indicate changes that are incompatible
- between OpenJPA 2.1.x releases and the 2.2.0 release.
-
-
-
- allocationSize Property of Sequence Generator
-
-
+
+ EntityManagerFactory lifecycle and properties
- In previous releases, specifying the allocationSize property of
- sequence generator
- affected only sequence definition in the database. During
- schema creation, the INCREMENT BY clause of
- CREATE SEQUENCE statement always
- had a value of 1 and on DB2, Oracle and PostgreSQL databases a CACHE clause
- was added with the value of allocationSize property. Such a statement caused
- sequence values being cached in the database. Starting with OpenJPA 2.2.0,
- sequence values are cached in the jvm memory and the allocationSize
- property determines size of that cache. The CACHE clause is no longer used,
- instead the INCREMENT BY clause gets its value equal to the
- allocationSize property. Such a strategy reduces the number of database roundtrips
- required for retrieving sequence values considerably.
+ EntityManagerFactory.close() could previously be called more than
+ once, and methods of a closed factory either worked or failed deep inside the kernel.
+ Now getProperties(), createEntityManager(),
+ getCriteriaBuilder(), getMetamodel(),
+ getPersistenceUnitUtil() and
+ getSchemaManager() throw IllegalStateException
+ after close(), and a second close() throws as
+ well. createEntityManager(SynchronizationType.UNSYNCHRONIZED)
+ throws IllegalStateException instead of
+ UnsupportedOperationException (it is forbidden for
+ RESOURCE_LOCAL units and still unimplemented for JTA units).
- In order for the existing applications to work with OpenJPA
- 2.2.0, you have to manually recreate or redefine sequences, specifying
- the correct INCREMENT BY value and, possibly, correct initial sequence value.
- Note that the default value of the allocationSize property is 50 and that
- value is used if the property is not specified.
+ EntityManagerFactory.getProperties() no longer creates a temporary
+ EntityManager to merge EntityManager-level
+ defaults (lock timeout, cache modes, fetch plan settings) into its result, and
+ null-valued entries are removed; read such defaults from
+ EntityManager.getProperties() instead.
+ addNamedQuery() now replaces an existing definition of the same
+ name and records flush mode, max results and lock mode; Criteria queries are stored
+ as JPQL text, which is not guaranteed to round-trip for complex criteria.
+
+
+ Query parameter API
- The requirement for sequence modification applies to all databases that support sequences, regardless of
- the CACHE clause being supported. The only exception is Firebird database -
- since with this database the increment step is determined during sequence
- value fetch, no migration activity is needed.
+ Reading an unbound parameter via getParameterValue() now throws
+ IllegalStateException (previously
+ IllegalArgumentException or null);
+ Parameter objects obtained from another query are rejected
+ with IllegalArgumentException;
+ getParameter(String, Class) now correctly accepts an exact or
+ wider type (the positional variant getParameter(int, Class) still
+ only accepts the exact type or a subtype). A parameter bound with
+ TemporalType.DATE is converted to java.sql.Date
+ (time of day dropped) instead of being passed through unchanged.
- To maintain the old behavior of sequence generator in OpenJPA 2.2.0, you can:
-
-
-
- Set the allocationSize property value to 1.
-
-
-
-
- Additionally, if the CACHE clause has to be emitted in sequence definition,
- this can be accomplished by overriding the
-
- DBDictionary.getCreateSequenceSQL method.
-
-
-
+ Catch IllegalStateException for unbound parameters and expect
+ java.sql.Date semantics for DATE-typed
+ parameters compared against TIMESTAMP columns.
-
-
- MetaModel Attributes for Arrays
-
-
+
+ StoredProcedureQuery semantics
- In previous releases OpenJPA's MetaModel implementation generated a ListAttribute for every array. This behavior is correct if the array
- is annotated as a PersistentCollection, but not correct for un-annotated arrays (e.g. byte[], char[]). In OpenJPA 2.2.0 this behavior was corrected
- so that arrays which are not stored as PersistentCollections will use a SingularAttribute instead of a ListAttribute.
+ Positional stored procedure parameters are now resolved 1-based (previously the
+ 0-based column index was used as fallback, so position 1 could match the second
+ IN column), and only IN/INOUT/
+ OUT columns are registered, so positional indexes shift for
+ PostgreSQL functions with a return value. When a procedure declares
+ OUT parameters the connection is kept open (with auto-commit
+ temporarily disabled) until the result list is closed, so that
+ REF_CURSOR results can be consumed; consume and close such
+ result lists promptly.
- If your application uses the MetaModel API and your entities contain arrays of any of the following types: byte[], Byte[], char[], Character[] and
- do not use the @PersistentCollection annotation with those fields you will need to update your application to use OpenJPA 2.2.0.
-
- In order for the existing applications to work with OpenJPA you may:
-
-
- Regenerate the canonical metamodel classes
-
-
- Set the Compatibility property UseListAttributeForArrays to true in persistence.xml
- <property name="openjpa.Compatibility" value="UseListAttributeForArrays=true"/>
-
-
-
+ executeUpdate() now requires an active transaction
+ (TransactionRequiredException) and
+ getUpdateCount() returns -1 after it;
+ setLockMode()/getLockMode() throw
+ IllegalStateException;
+ getOutputParameterValue() throws
+ IllegalArgumentException for unknown names or positions;
+ NoResultException and
+ NonUniqueResultException propagate unwrapped; procedure
+ metadata lookup retries with the lower-cased name; an
+ orm.xmlnamed-stored-procedure-query overrides
+ an annotation of the same name.
-
-
- supportsSetClob Property.
-
-
+
+ Criteria API and Metamodel
- In OpenJPA 2.2.0, code was added to allow the setting of CLOB or XML data larger than 4000 bytes. This functionality
- was eventually back ported to previous releases, and enabled by the supportsSetClob property on the OracleDictionary. Setting this property
- has no effect in 2.2.0 and later releases and any occurrence of it should be removed.
+ Several OpenJPA extensions and lenient behaviors of the Criteria API were tightened
+ to the specification: CriteriaBuilder.array()/tuple()
+ reject nested compound selections and multiselect()/select()
+ reject duplicate aliases with IllegalArgumentException;
+ cb.literal(null) throws IllegalArgumentException
+ (use nullLiteral(Class)); Path.get() on a basic
+ path and From.getCorrelationParent() on a non-correlated
+ From throw IllegalStateException;
+ Metamodel.entity(Class)/embeddable(Class) throw
+ IllegalArgumentException for unknown types instead of
+ returning null; ParameterExpression.getPosition()
+ returns null (previously threw an internal exception).
+
+
+ Embeddable-typed attributes are no longer reported as associations
+ (isAssociation() is false,
+ getBindableType() is SINGULAR_ATTRIBUTE),
+ getBindableJavaType() returns the declared attribute type, and
+ getId(Class)/getDeclaredId(Class) require strict
+ type assignability. cb.treat(Root, Class) is now implemented;
+ treat() on joins and paths returns the argument unchanged without
+ narrowing, and TREAT only matches the exact treated class, not its
+ subclasses. Flatten nested selections, use unique aliases and adjust catch blocks
+ and null checks accordingly.
-
-
- useNativeSequenceCache Property.
-
-
+
+ PersistenceUnitUtil.getIdentifier() returns the plain identifier
- In OpenJPA 2.2.0, code was added which changed the way sequences were generated, please see
- for details. This functionality was eventually back ported
- to previous releases, and enabled by the useNativeSequenceCache property on the DBDictionary. Setting this property
- has no effect in 2.2.0 and later releases and any occurrence of it should be removed. If previous behavior is
- desired (i.e. useNativeSequenceCache=true), please see the details described in section
- .
+ PersistenceUnitUtil.getIdentifier() previously returned the
+ internal org.apache.openjpa.util.OpenJPAId wrapper
+ (LongId, StringId, ...) for managed
+ entities and null for new, detached or unenhanced entities and
+ for non-entities. It now returns the raw identifier value (the plain key or the
+ IdClass instance for compound identity), also for new, detached
+ and unenhanced entities, and throws IllegalArgumentException
+ for objects that are not entities. Code that cast the result to
+ OpenJPAId must use the plain value or call
+ OpenJPAEntityManager.getObjectId().
-
-
- Cascade persist behavior
-
-
+
+ Cache mode properties on EntityManager.setProperty()
- In previous releases, OpenJPA would check the database for the
- existence of the related Entity before persisting the relationship to
- that Entity. This resulted in an extra Select being sent to the
- database. In 2.2.0, code was added so that when cascading a persist to
- a related Entity without persistence state, the persist (insert) will
- happen without first checking the database. This may result in an
- EntityExistsException if the related Entity already exists in the
- database. To revert this behavior to the previous release, set the
- value of the openjpa.Compatibility
- property CheckDatabaseForCascadePersistToDetachedEntity
- to true.
+ EntityManager.setProperty("jakarta.persistence.cache.retrieveMode", ...)
+ and "jakarta.persistence.cache.storeMode" previously accepted the
+ enum constants as well as their String names. The new
+ Jakarta Persistence 3.2 setters setCacheRetrieveMode() and
+ setCacheStoreMode() are now used to apply these properties, and
+ a String value is passed to the setter unconverted, which
+ fails with an IllegalArgumentException (argument type
+ mismatch); previously the call succeeded. Pass the
+ CacheRetrieveMode/CacheStoreMode enum
+ constant, or call the setters directly. String values given
+ as find(), refresh() or query hints continue
+ to work.
-
-
- Life Cycle Event Manager Callback Behavior
-
-
+
+ Default map key column renamed to <field>_KEY
- Life cycle event manager is used to manage entity's life cycle event callback.
- In previous releases, Life cycle event manager is scoped to EntityManagerFactory.
- This means listeners registered to an individual EntityManager may get life cycle
- event callbacks for entity that it does not manage.
+ For Map-valued fields without @MapKeyColumn
+ the key column was previously named KEY (which most dictionaries
+ turned into KEY0 because KEY is a reserved
+ word). As required by section 11.1.35 of the specification, the default is now the
+ field name followed by _KEY (for example
+ PHONES_KEY). Schemas created by earlier releases no longer match:
+ schema validation fails, SynchronizeMappings=buildSchema adds a
+ new column and existing key data reads back as null.
- From 2.2.1 release, the default callback behavior of the life cycle event manager
- is changed to scope to each EntityManager.
- To revert this behavior to the previous release, set the
- value of the openjpa.Compatibility
- property SingletonLifecycleEventManager
- to true.
+ Declare the existing column explicitly, for example
+ @MapKeyColumn(name="KEY0"), or rename the column in the
+ database. No compatibility option restores the old default. See also
+ .
-
-
- shared-cache-mode Property
-
-
+
+ Attribute overrides, @OrderBy and inverse map keys
- In the previous release, when the shared-cache-mode is enabled and the DataCache property is not set
- or set to false, there will be no data caching.
+ @AttributeOverride on an entity now also applies to the entity's
+ own declared fields (previously only mapped superclass fields were overridden), and
+ an override name without key./value. prefix on
+ an element collection Map refers to the map value instead of
+ failing. Attribute names in @OrderBy and overrides are resolved
+ case-insensitively as a fallback. @MapKeyColumn on the inverse
+ side of a @OneToMany(mappedBy) map is now written to the target
+ entity's table (additional UPDATE statements), and an
+ @ElementCollection whose table coincides with an entity's primary
+ table is no longer written separately.
- From 2.2.2 release, the caching will be turned on if the shared-cache-mode is enabled. Please see the
- details described in section .
+ Verify the column names produced by overrides that were previously ignored or
+ rejected, and @OrderBy values that differ from attribute names
+ only in case.
-
-
-
-
- OpenJPA 2.3.0
-
-
- Incompatibilities
-
- The following sections indicate changes that are incompatible
- between OpenJPA 2.2.x releases and the 2.3.0 release.
-
-
-
- MappingTool Behavior for DB2 and Derby
-
+
+ @SequenceGenerator without sequenceName
- In previous releases, the MappingTool mapped java.math.BigDecimal fields to the database type
- DOUBLE, and as such, ignored column and precision values that might have been specified via the
- jakarta.persistence.Column annotation.
+ A @SequenceGenerator annotation without
+ sequenceName previously fell back to the OpenJPA default
+ sequence OPENJPA_SEQUENCE, so all such generators shared one
+ database sequence. As defined by the specification, the generator name is now used
+ as the database sequence name, and DDL generation creates one sequence per
+ generator. orm.xmlsequence-generator elements
+ are not affected.
- From the 2.3.0 release, java.math.BigDecimal fields are now mapped to the database type DECIMAL
- and it is very likely that you will need to specify column and precision via
- the jakarta.persistence.Column annotation.
+ For existing databases either add sequenceName="OPENJPA_SEQUENCE"
+ (or the previously used name) to each generator, or create the new per-generator
+ sequences. See .
-
-
- RequiresSearchStringEscapeForLike DBDictionary Property
-
-
+
+ AttributeConverter handling
- In previous releases, the default value for the property RequiresSearchStringEscapeForLike is true and caused the
- unexpected escape clause appended to the SQL statement.
- For example, user created a named query like this:
- SELECT o.computerName FROM CompUser o WHERE o.name LIKE ?
- At run time the following query is generated:
- SELECT t0.computerName FROM CompUser t0 WHERE (t0.name LIKE ? ESCAPE '\')
- ESCAPE '\' shouldn't be appended to the query.
+ Support for jakarta.persistence.AttributeConverter was reworked.
+ @Converter(autoApply=true) classes found on the classpath are now
+ registered and applied to every basic attribute whose declared type matches
+ (excluding identifiers, version fields, relations, collections and maps) unless
+ the attribute declares its own @Convert; previously
+ autoApply was ignored. Class-level
+ @Convert(attributeName=...)/@Converts,
+ converters on embedded attributes, on mapped superclass attributes and on element
+ collection elements are honored (previously ignored or rejected). The database
+ column type is now derived from the converter's database type
+ Y instead of the attribute type X
+ (a Boolean to Integer converter now
+ yields an INTEGER column).
- From the 2.3.0 release, RequiresSearchStringEscapeForLike property is set to false by default. You can configure
- RequiresSearchStringEscapeForLike property to be true if the old behavior is desired.
+ One converter instance per attribute is created lazily through the no-argument
+ constructor and shared between threads, so converters must be stateless.
+ RuntimeExceptions thrown by a converter surface as
+ jakarta.persistence.PersistenceException instead of
+ MetaDataException. @Convert(disableConversion=true)
+ only cancels an explicit converter on that attribute; it does not prevent an
+ autoApply converter from being applied.
+
+
+ Audit existing @Converter(autoApply=true) classes: attributes of
+ the matching type that were stored unconverted by 4.1.x are now written and read
+ through the converter and their generated column type changes. Remove
+ autoApply, declare an explicit converter, or pin the column type
+ with @Column(columnDefinition=...) where the old behavior is
+ required.
-
-
- Return value of aggregate functions in SELECT clause
-
-
+
+ Access type determination and property accessors
- The JPA specification states "If SUM, AVG, MAX, or MIN is used, and there are no values to which the aggregate function can be
- applied, the result of the aggregate function is NULL." Prior to this update, OpenJPA incorrectly returned 0 for SUM, AVG, MIN,
- and MAX when a state field being aggregated is numeric. This behavior affects both JPQL and Criteria queries. With this update,
- OpenJPA will return a null result value for these aggregate functions when a query returns no result.
+ Implicit access type determination now follows the specification: only
+ access-defining annotations (@Id, @EmbeddedId,
+ @Version, @Basic, @Embedded,
+ the relationship annotations, @ElementCollection,
+ @Transient) decide the access type; supplementary annotations
+ such as @Column or @Temporal only count when
+ no access-defining annotation is present. A getter whose backing field is
+ @Transient is a per-attribute property override and no longer
+ makes the class "mixed"; an attribute annotated on both field and getter uses
+ property access; a subclass whose implicit access conflicts with its persistent
+ superclass inherits the superclass access type (previously an error);
+ @Basic may be combined with a more specific mapping annotation;
+ records always use field access; types declared as embeddable
+ only in orm.xml are mapped as embedded rather than serialized.
- To re-enable the prior behavior, you need to set the following persistence property in your persistence.xml or when
- creating an EntityManagerFactory.
-
- <property name="openjpa.Compatibility" value="ReturnNullOnAggregateResult=false"/>
-
+ Boolean getters must have an upper-case character after is
+ (island() or isaBoolean() are no longer
+ persistent properties), and the setter for a property is derived from the actual
+ getter suffix (getdescription()/setdescription()
+ pairs are accepted). Entities that previously failed to load may now load with a
+ different access type than intended; add an explicit @Access
+ where fields and getters are both annotated, and review unusual boolean accessor
+ names. No compatibility option exists.
-
-
-
- OpenJPA 3.2.0
-
- Incompatibilities
-
- The following sections indicate changes that are incompatible
- between OpenJPA 3.1.x releases and the 3.2.0 release.
-
-
- SUM now always returns Double
+
+ java.time.Instant and java.time.Year mapping
- We did fix the SUM operation to always return Double as requested by the spec.
- Previously we did return whatever Numeric the JDBC driver did serve, resulting in non portable code.
+ java.time.Instant and java.time.Year
+ are now first-class persistent types: Instant maps to a
+ TIMESTAMP column and Year to an
+ INTEGER column. Previous releases had no type code for them and
+ stored such attributes through the generic object strategy as serialized binary
+ data. Existing columns created for such attributes are incompatible with the new
+ mapping: migrate the columns and data, or keep them serialized explicitly with
+ @Lob or an externalizer. java.util.Calendar
+ may now be used as a single-field identifier.
-
- Invalid Column Name Changes
+
+ Generated DDL changes
- We did review and update the list of invalid column names for most DBDicationary.
- The list of tested reserved words got enriched with previously forbidden column names to avoid backward
- incompatibility issues.
- The list can ge retrieved and configured via
-
- DBDictionary.getInvalidColumnWordSet
+ The DDL produced by the mapping tool,
+ and the new SchemaManager differs from previous releases:
+
+
+ jakarta.persistence.ForeignKey on
+ @JoinColumn, @JoinTable and
+ @SecondaryTable is now parsed. A named constraint
+ (ConstraintMode.CONSTRAINT) is emitted as a physical
+ foreign key even for relations that OpenJPA treats as logical;
+ NO_CONSTRAINT suppresses the key;
+ PROVIDER_DEFAULT keeps the 4.1.x behavior. Expect
+ additional ALTER TABLE ... ADD CONSTRAINT statements
+ and a stricter drop order.
+
+
+ Every declared @SecondaryTable is created, even if no
+ field is mapped to it.
+
+
+ The table-level comment is no longer emitted in
+ CREATE TABLE (column comments remain).
+
+
+ @Index(columnList="col DESC") is honored,
+ @JoinTable.indexes are created,
+ @Table(options) and @Column(options)
+ are appended verbatim, and @Column(secondPrecision)
+ takes precedence over scale and the dictionary's
+ DateFractionDigits for temporal columns.
+
+
+
+
+ Compare generated DDL against existing schemas before enabling schema
+ synchronization in production.
-
- MappingTool Behavior for HSQLDB
+
+ Jakarta Persistence schema generation and SQL scripts
- There have been 2 changes for Hypersonic (HSQLDB).
- We fixed a bug which did cause long fields getting mapped to INTEGER
- instead of BIGINT.
+ The jakarta.persistence.schema-generation.* properties are now
+ honored as described by the specification: scripts.action is
+ mapped to schema tool actions on its own (previously only
+ database.action was considered) and scripts are generated or
+ executed when the EntityManagerFactory is created rather
+ than lazily with the first EntityManager; explicit
+ create-source/drop-source values are
+ respected; java.io.Writer/Reader
+ targets and sources, file: URIs and absolute paths are accepted.
+ When Writer/Reader objects are
+ supplied, the corresponding keys are removed from the caller's property map, so the
+ map must be mutable. Persistence.generateSchema() defaults
+ database.action=create only if neither
+ database.action nor scripts.action is given.
+ A table dropped by an executed drop script is skipped by the next
+ buildSchema/add run in the same JVM (once by
+ default; until an EntityManagerFactory with schema-generation
+ properties starts when openjpa.SpecCompliantSchemaGeneration=true)
+ instead of being silently re-created.
- Java double fields previously got mapped to NUMERIC which
- does lack fraction digits. Thus the value 7.3425343 got truncated to 7.
- We now map double fields in Entities to DOUBLE SQL column types.
+ SQL scripts (create, drop and load scripts) are now parsed as
+ ;-terminated statements that may span several lines, with
+ --, // and /* ... */
+ comments stripped (string literals are not recognized). Previously every line was
+ one statement. Errors in scripts executed through schema generation are logged as
+ warnings on the channel instead of failing
+ start-up. Terminate every statement with ; and check the log
+ for script errors. Related SchemaTool changes: table
+ truncation continues after failing statements, dropping the last column of a table
+ drops the whole table, and the new DBDictionary.isDroppable(Sequence)
+ hook excludes system sequences.
+
+
+ Two options were added. openjpa.SpecCompliantSchemaGeneration=true
+ (also available as openjpa.Compatibility=SpecCompliantSchemaGeneration=true,
+ default false) enables strict Jakarta Persistence semantics: a
+ schema-generation configuration that resolves to no action (for example
+ database.action=none) also disables
+ openjpa.jdbc.SynchronizeMappings, @MapsId
+ foreign key columns are named <relation>_<targetPk>,
+ and on PostgreSQL identifiers are never quoted. Do not enable it on existing
+ databases created by earlier releases. The option
+ openjpa.jdbc.SyncMappingsExcludeTypes=a.B;c.D (or
+ SynchronizeMappings=buildSchema(ExcludeTypes=a.B;c.D)) excludes
+ entity classes from schema synchronization and drops their existing tables; only
+ list entities whose tables may be destroyed. See
+ and
+ .
+
+
+
+ Numeric versus character column type conflicts
+
+ When two mappings, or the mapping and the reflected database column, disagreed on
+ an incompatible column type, previous releases failed with a
+ -bad-colMetaDataException (or logged a
+ warning with disableSchemaFactoryColumnTypeErrors). Conflicts
+ between numeric and character types are now silently resolved to
+ VARCHAR, and values are converted on read and write. As a side
+ effect, SynchronizeMappings=validate and
+ SchemaManager.validate() no longer report numeric versus
+ VARCHAR drift; verify such columns manually. All other
+ incompatible combinations still fail as before.
+
+
+
+ DELETE affecting zero rows tolerated for unversioned entities
+
+ A DELETE statement reporting an update count of zero previously
+ always raised an OptimisticException, including rows already
+ removed by a database-level ON DELETE CASCADE. For entities
+ without a version strategy (no @Version and no state comparison
+ versioning) such a delete is now silently accepted. Entities with a version
+ strategy behave as before. Applications that relied on the exception to detect a
+ concurrently deleted unversioned row should add a @Version
+ attribute; subclasses of PreparedStatementManagerImpl may
+ override hasVersion(RowImpl).
+
+
+
+ Non-entity classes in persistence.xml
+
+ Listing a class without persistence metadata in a persistence unit
+ (class element) previously failed at start-up with
+ "No registered metadata for type", in the runtime enhancer, in
+ getMetamodel() and during schema synchronization. Such classes
+ are now skipped with a warning on the openjpa.Enhance and
+ openjpa.jdbc.Schema logs. A forgotten @Entity
+ annotation is therefore no longer detected at start-up; watch the logs for the new
+ warnings.
+
+
+
+ Relaxed kernel checks
+
+ Several early exceptions were relaxed to satisfy the specification:
+ a non-cascaded relation pointing at an object without a state manager is no longer
+ rejected at flush with "cant-cascade-persist"; the referenced row is looked up in
+ the database during flush (an extra SELECT for unenhanced or
+ subclass-enhanced entities) and truly transient references may now fail later with
+ a foreign key error. Modifying an embeddable obtained from a query projection no
+ longer throws; the modification is silently not persisted. Re-persisting an entity
+ after remove() and flush is tolerated. In addition,
+ orphanRemoval=true no longer downgrades
+ cascade=REMOVE/ALL, so removal is cascaded
+ immediately when both are combined.
+
+
+
+ Insert ordering across logical foreign keys
+
+ Flush ordering previously delayed an insert only for physical (constraint-backed)
+ foreign keys. Rows related through logical foreign keys (no constraint declared in
+ the mapping, for example an externally created schema with real constraints) are
+ now also delayed until the referenced new row has been inserted. Statement order
+ at flush time may therefore change; tests asserting an exact SQL order may need to
+ be adjusted. There is no configuration switch.
+
+
+
+ Enhancer and runtime enhancement
+
+ Classes enhanced by this release call new runtime methods (for example
+ ApplicationIds.getRelatedObjectId() for derived identities) and
+ fail on a 4.1.x runtime, while classes enhanced by 4.1.x still load but miss the
+ fixes of this release. Re-run the build-time enhancer
+ () with 4.2.0 when upgrading.
+
+
+ Runtime enhancement ( and the
+ Java agent) changed: class redefinition uses
+ Instrumentation.redefineClasses() and, if it fails, OpenJPA logs
+ "redefineClasses failed" at INFO and silently falls back to
+ subclass enhancement instead of throwing. getClass() calls in
+ user equals()/hashCode() implementations of
+ subclass-enhanced entities now see the entity class instead of the generated
+ subclass, and generated writeReplace() methods work with
+ non-public no-argument constructors.
+
+
+
+ Delayed collection proxies on Java 21
+
+ The delay-loading collection proxies (openjpa.ProxyManager=default(DelayCollectionLoading=true),
+ see ) now declare the Java 21
+ SequencedCollection methods explicitly.
+ addFirst() and addLast() both delegate to
+ add(), so addFirst() appends instead of
+ prepending (previously DelayedLinkedListProxy prepended
+ after loading the collection), and reversed() returns a copy
+ rather than a write-through view for list and LinkedHashSet
+ proxies. Load the collection and reorder it explicitly where the position matters.
+ The ASM-generated non-delayed proxies are unchanged.
+
+
+
+ Static metamodel generator output
+
+ Generated X_ classes now contain the Jakarta Persistence 3.2
+ class_ field and QUERY_<NAME> /
+ MAPPING_<NAME> constants for named queries and result set
+ mappings declared on the type, and are annotated with
+ javax.annotation.processing.Generated instead of
+ jakarta.annotation.Generated when available. Regenerate the
+ metamodel classes and watch for name clashes with attributes named
+ class_.
+
+
+
+ Lifecycle callbacks and listeners
+
+ Default entity listeners declared in several mapping files are now registered once
+ instead of once per file, and a callback declared both by annotation and in
+ orm.xml for the same method is registered once with the XML
+ declaration taking precedence. Callback parameter types are matched more leniently,
+ and listeners receive the managed entity instance (not the internal
+ ReflectingPersistenceCapable wrapper) on
+ AFTER_DELETE_PERFORMED for unenhanced entities. Applications that
+ depended on duplicate invocations must be adjusted.
+
+
+
+ persistence.xml resource handling
+
+ An I/O error while reading a persistence.xml resource from the
+ classpath previously aborted createEntityManagerFactory(). Such
+ resources are now logged ("unreadable-persistence-xml") and skipped; schema
+ validation errors still abort. A unit that only exists in a skipped resource
+ surfaces later as a missing persistence unit. Resource streams are opened with
+ URL connection caching disabled. The 3.2 elements scope and
+ qualifier are exposed through
+ PersistenceUnitInfo.
+
+
+
+ Locale-independent case conversion
+
+ Identifier normalization, JPQL parsing, in-memory LOWER()/
+ UPPER() evaluation and SQL formatting used the JVM default
+ locale for case conversion. They now use Locale.ROOT
+ (Locale.ENGLISH for reserved word matching). This is only
+ observable under locales with special casing rules (Turkish, Azeri, Lithuanian),
+ where generated identifiers containing i/I
+ may now differ from those generated by earlier releases; use explicit
+ @Table/@Column names in that case.
+
+
+
+ Reserved word handling and MySQL delimiting
+
+ Reserved word detection is now case-insensitive for all dictionaries, so generated
+ (defaulted) column, table and sequence names that equal a reserved word in a
+ different case may now receive a 0 suffix.
+ H2Dictionary additionally feeds its H2 2.x keyword list into
+ the naming rules. On MySQL (MySQLDictionary, not
+ MariaDBDictionary) reserved word identifiers are now
+ automatically delimited with back-ticks in all generated SQL, so previously
+ failing names such as KEY, TEXT or
+ LIBRARY work without manual delimiting. Tools comparing SQL text
+ must ignore the delimiters. Use explicit @Table/@Column
+ names if an old generated name must be kept. See
+ .
+
+
+
+ PostgreSQL
+
+ Delimited identifiers: PostgresDictionary now strips the
+ double quotes from a quoted identifier whose inner text is a plain identifier
+ (letters, digits and underscores, not starting with a digit). PostgreSQL then folds
+ the name to lower case, so @Table(name="\"MyTable\"") now
+ addresses mytable and quoted reserved words such as
+ "Order" become bare keywords. Identifiers containing spaces or
+ other special characters keep their quotes. Do not rely on delimited identifiers to
+ preserve mixed case or to use reserved words as names on PostgreSQL; rename the
+ objects, or subclass PostgresDictionary and override
+ toDBName(). There is no configuration switch.
+
+
+ char/Character attributes: on PostgreSQL 9
+ and later StoreCharsAsNumbers now defaults to
+ false, so such attributes map to CHAR(1)
+ columns instead of INTEGER columns holding code points, and the
+ Java default '\0' is stored as SQL NULL.
+ Existing INTEGER columns created by earlier releases fail
+ validation or return wrong values. Either migrate them to
+ CHAR(1) or restore the previous mapping with
+ openjpa.jdbc.DBDictionary=postgres(StoreCharsAsNumbers=true);
+ an explicitly configured value is respected (OPENJPA-2971).
+
+
+ Further fixes: java.util.UUID parameters are bound so that
+ both native uuid and varchar columns work (on
+ other databases a UUID is bound as VARCHAR unless the column is
+ a native UUID column); @Lob columns of type oid
+ are read and written through the large object API, which performs an implicit
+ COMMIT when reading in auto-commit mode; reflected
+ bool columns are reported as BOOLEAN, so
+ schema validation may now report boolean versus varchar drift that was previously
+ tolerated; DROP SEQUENCE IF EXISTS is emitted.
+
+
+
+ MySQL and MariaDB
+
+ On MySQL 5.7+ and MariaDB 10.2+ temporal columns are now created as
+ DATETIME(6) and TIME(6)
+ (DateFractionDigits=6) instead of whole-second precision, so that
+ @Version attributes of type Instant or
+ LocalDateTime can distinguish updates within the same second.
+ The value is set at connection time and overrides a
+ DateFractionDigits value given in
+ . Existing columns keep working, but
+ schema validation or refresh may report or alter the precision. Use
+ @Column(secondPrecision=0) on individual columns, or subclass the
+ dictionary and reset dateFractionDigits after
+ connectedConfiguration(), to keep whole seconds.
+
+
+ MariaDBDictionary no longer replaces a configured positive
+ with Integer.MIN_VALUE
+ (the Connector/J 2.x streaming mode); the configured value is passed to the driver
+ unchanged. MySQLDictionary keeps the streaming behavior.
+ Subclass MariaDBDictionary and override
+ getBatchFetchSize(int) to restore streaming.
+
+
+
+ Microsoft SQL Server
+
+ CURRENT_DATE and CURRENT_TIME are now
+ translated to CONVERT(DATE, GETDATE()) and
+ CONVERT(TIME, GETDATE()) instead of plain
+ GETDATE(), so the results are DATE/TIME
+ typed and comparisons against datetime columns may behave
+ differently. EXTRACT uses DATEPART and JPQL
+ time literals are rendered as CAST('hh:mm:ss' AS TIME). To
+ restore the previous SQL set
+ openjpa.jdbc.DBDictionary=sqlserver(CurrentDateFunction=GETDATE(),CurrentTimeFunction=GETDATE()).
+
+
+
+ Oracle
+
+ Identity column sequences (ISEQ$$_*) are treated as system
+ sequences and excluded from drop actions, AUDSYS is treated as a
+ system schema, an @Index duplicating the primary key is skipped,
+ CEILING() is translated to CEIL(), and the new
+ Jakarta Persistence 3.2 functions are mapped to Oracle syntax
+ (EXCEPT as MINUS before Oracle 21,
+ LEFT/RIGHT via SUBSTR).
+ These are fixes; workarounds for the old behavior can be removed.
+
+
+
+ HSQLDB
+
+ HSQLDictionary no longer disables
+ SupportsSelectForUpdate, so pessimistic locks now emit
+ SELECT ... FOR UPDATE; query timeouts are disabled
+ (SupportsQueryTimeout=false); OffsetTime
+ attributes are created as TIME instead of
+ TIME WITH TIME ZONE; numeric casts are sized
+ NUMERIC(128,32) so fractional digits are no longer truncated;
+ INFORMATION_SCHEMA and SYSTEM_LOBS are treated
+ as system schemas. Use openjpa.jdbc.DBDictionary=hsql(SupportsSelectForUpdate=false,SupportsQueryTimeout=true)
+ and @Column(columnDefinition="TIME WITH TIME ZONE") to restore
+ the previous behavior. On H2 2.x, table truncation now skips the
+ INFORMATION_SCHEMA meta tables.
+
+
+
+ SPI changes for custom store, dictionary and expression implementations
+
+ Implementors of OpenJPA SPI interfaces must recompile and implement new methods:
+ BrokerFactory (createPersistenceStructure,
+ dropPersistenceStructure, validatePersistenceStructure,
+ truncateData; AbstractBrokerFactory
+ throws UnsupportedOperationException by default),
+ ExpressionFactory (newTypecastAsString,
+ newTypecastAsNumber, left, right,
+ replace, getNativeObjectId, version),
+ Result (getInstant, getYear),
+ Select (appendNullsPrecedence,
+ addSetOperatorSQL, getSetOperatorBuffer),
+ OpenJPAConfiguration (schema generation script accessors,
+ isSchemaGenerationExplicit, isSpecCompliantSchemaGeneration)
+ and JDBCConfiguration (get/setSyncMappingsExcludeTypes).
+
+
+ DBDictionary.SerializedData is now a record
+ (bytes() instead of the bytes field);
+ IdentifierRule.setReservedWords takes a
+ Collection and matches case-insensitively, so subclasses
+ overriding the Set variant no longer override;
+ JavaTypes.INSTANT (39) and JavaTypes.YEAR (40)
+ were added and must be handled by custom value handlers and strategies;
+ QueryExpressions gained nullPrecedence,
+ setOperationType and setOperands, which only
+ the JDBC store consumes, so a custom StoreQuery silently ignores
+ NULLS FIRST/LAST and set operations unless it is extended.
+ DBDictionary gained a number of public configuration fields
+ (ReplaceFunctionName, LeftFunctionName,
+ RightFunctionName, NaturalLogarithmFunction,
+ CeilingFunction, ExceptFunction,
+ TypecastToStringTypeName, IntegerCastTypeName,
+ SupportsUnsizedCharOnCast) and hooks
+ (isDroppable(Sequence), toJDBCEscapedDateTimeLiteral,
+ appendNullsPrecedence, getExtractField,
+ get/setMajorVersion, get/setMinorVersion).
+
+
+
+ Notable new features
+
+ The following Jakarta Persistence 3.2 features are new in this release. They are
+ opt-in and do not change existing behavior unless noted:
+
+
+ JPQL: ID() and VERSION() functions,
+ CAST, LEFT, RIGHT,
+ REPLACE, the || operator,
+ UNION/INTERSECT/EXCEPT [ALL],
+ NULLS FIRST/LAST, TREAT in joins and
+ paths, JOIN ... ON, EXTRACT,
+ LOCAL DATE/TIME/DATETIME, additional math functions,
+ an optional SELECT clause and the implicit
+ this identification variable (bound automatically when a
+ FROM item declares no identification variable). See .
+ In-memory query execution (and custom StoreQuery
+ implementations) silently ignore
+ UNION/INTERSECT/EXCEPT
+ and NULLS FIRST/LAST;
+ LEFT/RIGHT, CAST and
+ EXTRACT are not available on Derby.
+
+
+ EntityManager: find(),
+ lock() and refresh() with
+ FindOption/LockOption/RefreshOption,
+ getReference(entity), cache mode and timeout accessors,
+ runWithConnection()/callWithConnection(),
+ createQuery(CriteriaSelect);
+ Query: getSingleResultOrNull(),
+ cache mode and timeout setters.
+
+
+ EntityManagerFactory:
+ runInTransaction()/callInTransaction()
+ (exceptions are rethrown wrapped in
+ org.apache.openjpa.persistence.PersistenceException),
+ getSchemaManager(), getName(),
+ getTransactionType(), getNamedEntityGraphs();
+ PersistenceUnitUtil: getVersion(),
+ isInstance(), getClass(),
+ load(); programmatic bootstrap via
+ Persistence.createEntityManagerFactory(PersistenceConfiguration)
+ and the jakarta.persistence.dataSource property.
+ EntityManager.find(EntityGraph, ...),
+ createQuery(TypedQueryReference),
+ getNamedQueries() and
+ SynchronizationType.UNSYNCHRONIZED are not yet implemented.
+
+
+ Entity graphs (@NamedEntityGraph,
+ createEntityGraph(), getEntityGraph()),
+ CriteriaUpdate, CriteriaDelete,
+ CriteriaSelect set operations,
+ Join.on(), CriteriaBuilder.cast()/
+ left()/right()/replace()/
+ extract() and treat(Root), all of which
+ previously threw UnsupportedOperationException.
+
+
+ Mapping: Java records as @Embeddable (records are
+ always treated as managed types, regardless of
+ openjpa.RuntimeUnenhancedClasses),
+ @EnumeratedValue (an enum declaring such a field changes
+ its stored representation), @Version on
+ java.time.Instant and
+ java.time.LocalDateTime (give such columns at least
+ microsecond precision), @Column(secondPrecision, options),
+ @Table(options), repeatable
+ @SequenceGenerator/@TableGenerator,
+ ConstructorResult in result set mappings, inline result
+ mappings on @NamedNativeQuery, orm.xml
+ version 3.2, id classes without a public no-argument constructor, and
+ @MapsId with non-embeddable id classes.
+
+
+ jakarta.persistence.ForeignKey,
+ @Index sort order, @JoinTable.indexes
+ and @Converter(autoApply=true) are honored (see the
+ respective sections above for the effect on existing schemas).
+
+
+ The bundled Jakarta Persistence schemas are now included under the Eclipse
+ Foundation Specification License 1.1 instead of the CDDL.
+
+
+
+
+
+
+
+ OpenJPA 3.2.0
+
+ Incompatibilities
+
+ The following sections indicate changes that are incompatible
+ between OpenJPA 3.1.x releases and the 3.2.0 release.
+
+
+ SUM now always returns Double
+
+ We did fix the SUM operation to always return Double as requested by the spec.
+ Previously we did return whatever Numeric the JDBC driver did serve, resulting in non portable code.
+
+
+
+ Invalid Column Name Changes
+
+ We did review and update the list of invalid column names for most DBDicationary.
+ The list of tested reserved words got enriched with previously forbidden column names to avoid backward
+ incompatibility issues.
+ The list can ge retrieved and configured via
+
+ DBDictionary.getInvalidColumnWordSet
+
+
+
+ MappingTool Behavior for HSQLDB
+
+ There have been 2 changes for Hypersonic (HSQLDB).
+ We fixed a bug which did cause long fields getting mapped to INTEGER
+ instead of BIGINT.
+
+
+ Java double fields previously got mapped to NUMERIC which
+ does lack fraction digits. Thus the value 7.3425343 got truncated to 7.
+ We now map double fields in Entities to DOUBLE SQL column types.
@@ -647,23 +1166,561 @@
DBDictionary.supportsQueryTimeout
-
- PostgreSQL stores char fields as CHAR by default
+
+
+
+
+ OpenJPA 2.3.0
+
+
+ Incompatibilities
+
+ The following sections indicate changes that are incompatible
+ between OpenJPA 2.2.x releases and the 2.3.0 release.
+
+
+
+ MappingTool Behavior for DB2 and Derby
+
+
+ In previous releases, the MappingTool mapped java.math.BigDecimal fields to the database type
+ DOUBLE, and as such, ignored column and precision values that might have been specified via the
+ jakarta.persistence.Column annotation.
+
+
+ From the 2.3.0 release, java.math.BigDecimal fields are now mapped to the database type DECIMAL
+ and it is very likely that you will need to specify column and precision via
+ the jakarta.persistence.Column annotation.
+
+
+
+
+ RequiresSearchStringEscapeForLike DBDictionary Property
+
+
+
+ In previous releases, the default value for the property RequiresSearchStringEscapeForLike is true and caused the
+ unexpected escape clause appended to the SQL statement.
+ For example, user created a named query like this:
+ SELECT o.computerName FROM CompUser o WHERE o.name LIKE ?
+ At run time the following query is generated:
+ SELECT t0.computerName FROM CompUser t0 WHERE (t0.name LIKE ? ESCAPE '\')
+ ESCAPE '\' shouldn't be appended to the query.
+
+
+ From the 2.3.0 release, RequiresSearchStringEscapeForLike property is set to false by default. You can configure
+ RequiresSearchStringEscapeForLike property to be true if the old behavior is desired.
+
+
+
+
+ Return value of aggregate functions in SELECT clause
+
+
+
+ The JPA specification states "If SUM, AVG, MAX, or MIN is used, and there are no values to which the aggregate function can be
+ applied, the result of the aggregate function is NULL." Prior to this update, OpenJPA incorrectly returned 0 for SUM, AVG, MIN,
+ and MAX when a state field being aggregated is numeric. This behavior affects both JPQL and Criteria queries. With this update,
+ OpenJPA will return a null result value for these aggregate functions when a query returns no result.
+
+
+ To re-enable the prior behavior, you need to set the following persistence property in your persistence.xml or when
+ creating an EntityManagerFactory.
+
+ <property name="openjpa.Compatibility" value="ReturnNullOnAggregateResult=false"/>
+
+
+
+
+
+
+
+ OpenJPA 2.2.0
+
+
+ Incompatibilities
+
+ The following sections indicate changes that are incompatible
+ between OpenJPA 2.1.x releases and the 2.2.0 release.
+
+
+
+ allocationSize Property of Sequence Generator
+
+
+
+ In previous releases, specifying the allocationSize property of
+ sequence generator
+ affected only sequence definition in the database. During
+ schema creation, the INCREMENT BY clause of
+ CREATE SEQUENCE statement always
+ had a value of 1 and on DB2, Oracle and PostgreSQL databases a CACHE clause
+ was added with the value of allocationSize property. Such a statement caused
+ sequence values being cached in the database. Starting with OpenJPA 2.2.0,
+ sequence values are cached in the jvm memory and the allocationSize
+ property determines size of that cache. The CACHE clause is no longer used,
+ instead the INCREMENT BY clause gets its value equal to the
+ allocationSize property. Such a strategy reduces the number of database roundtrips
+ required for retrieving sequence values considerably.
+
+
+ In order for the existing applications to work with OpenJPA
+ 2.2.0, you have to manually recreate or redefine sequences, specifying
+ the correct INCREMENT BY value and, possibly, correct initial sequence value.
+ Note that the default value of the allocationSize property is 50 and that
+ value is used if the property is not specified.
+
+
+ The requirement for sequence modification applies to all databases that support sequences, regardless of
+ the CACHE clause being supported. The only exception is Firebird database -
+ since with this database the increment step is determined during sequence
+ value fetch, no migration activity is needed.
+
+
+ To maintain the old behavior of sequence generator in OpenJPA 2.2.0, you can:
+
+
+
+ Set the allocationSize property value to 1.
+
+
+
+
+ Additionally, if the CACHE clause has to be emitted in sequence definition,
+ this can be accomplished by overriding the
+
+ DBDictionary.getCreateSequenceSQL method.
+
+
+
+
+
+
+
+ MetaModel Attributes for Arrays
+
+
- Previous releases stored Java char fields in numeric
- (INTEGER) columns on PostgreSQL, following the generic
- DBDictionary.StoreCharsAsNumbers=true default.
- Starting with this release, StoreCharsAsNumbers defaults to
- false on PostgreSQL 9 and later, so char
- fields are mapped to CHAR columns.
+ In previous releases OpenJPA's MetaModel implementation generated a ListAttribute for every array. This behavior is correct if the array
+ is annotated as a PersistentCollection, but not correct for un-annotated arrays (e.g. byte[], char[]). In OpenJPA 2.2.0 this behavior was corrected
+ so that arrays which are not stored as PersistentCollections will use a SingularAttribute instead of a ListAttribute.
- Existing schemas created by earlier OpenJPA releases must either migrate the
- affected columns to CHAR or restore the previous behaviour by
- setting the property explicitly, e.g.
- openjpa.jdbc.DBDictionary=postgres(StoreCharsAsNumbers=true).
- An explicitly configured value is always respected and never overridden by the
- PostgreSQL version detection.
+ If your application uses the MetaModel API and your entities contain arrays of any of the following types: byte[], Byte[], char[], Character[] and
+ do not use the @PersistentCollection annotation with those fields you will need to update your application to use OpenJPA 2.2.0.
+
+ In order for the existing applications to work with OpenJPA you may:
+
+
+ Regenerate the canonical metamodel classes
+
+
+ Set the Compatibility property UseListAttributeForArrays to true in persistence.xml
+ <property name="openjpa.Compatibility" value="UseListAttributeForArrays=true"/>
+
+
+
+
+
+
+
+ supportsSetClob Property.
+
+
+
+ In OpenJPA 2.2.0, code was added to allow the setting of CLOB or XML data larger than 4000 bytes. This functionality
+ was eventually back ported to previous releases, and enabled by the supportsSetClob property on the OracleDictionary. Setting this property
+ has no effect in 2.2.0 and later releases and any occurrence of it should be removed.
+
+
+
+
+ useNativeSequenceCache Property.
+
+
+
+ In OpenJPA 2.2.0, code was added which changed the way sequences were generated, please see
+ for details. This functionality was eventually back ported
+ to previous releases, and enabled by the useNativeSequenceCache property on the DBDictionary. Setting this property
+ has no effect in 2.2.0 and later releases and any occurrence of it should be removed. If previous behavior is
+ desired (i.e. useNativeSequenceCache=true), please see the details described in section
+ .
+
+
+
+
+ Cascade persist behavior
+
+
+
+ In previous releases, OpenJPA would check the database for the
+ existence of the related Entity before persisting the relationship to
+ that Entity. This resulted in an extra Select being sent to the
+ database. In 2.2.0, code was added so that when cascading a persist to
+ a related Entity without persistence state, the persist (insert) will
+ happen without first checking the database. This may result in an
+ EntityExistsException if the related Entity already exists in the
+ database. To revert this behavior to the previous release, set the
+ value of the openjpa.Compatibility
+ property CheckDatabaseForCascadePersistToDetachedEntity
+ to true.
+
+
+
+
+ Life Cycle Event Manager Callback Behavior
+
+
+
+ Life cycle event manager is used to manage entity's life cycle event callback.
+ In previous releases, Life cycle event manager is scoped to EntityManagerFactory.
+ This means listeners registered to an individual EntityManager may get life cycle
+ event callbacks for entity that it does not manage.
+
+
+ From 2.2.1 release, the default callback behavior of the life cycle event manager
+ is changed to scope to each EntityManager.
+ To revert this behavior to the previous release, set the
+ value of the openjpa.Compatibility
+ property SingletonLifecycleEventManager
+ to true.
+
+
+
+
+ shared-cache-mode Property
+
+
+
+ In the previous release, when the shared-cache-mode is enabled and the DataCache property is not set
+ or set to false, there will be no data caching.
+
+
+ From 2.2.2 release, the caching will be turned on if the shared-cache-mode is enabled. Please see the
+ details described in section .
+
+
+
+
+
+
+ OpenJPA 2.0.0
+
+
+
+ Incompatibilities
+
+
+
+ The following sections indicate changes that are incompatible
+ between OpenJPA 1.x.x releases and the 2.0 release. Some may
+ require application changes. Others can be remedied through the
+ use of compatibility options. If your application uses a
+ version 1.0 persistence.xml, compatibility options will be set
+ appropriately to maintain backward compatibility. OpenJPA 2.0
+ applications using a version 2.0 persistence.xml and requiring
+ OpenJPA 1.x.x compatibility may need to configure the
+ appropriate compatibility options to get the desired behavior.
+
+
+
+ getProperties()
+
+
+
+ The OpenJPAEntityManagerFactory interface getProperties()
+ method was changed to return a Map instead of a
+ Properties object. This change was made in order to
+ support the getProperties() method defined in the
+ JPA 2.0 specification.
+
+
+
+
+ Detach Behavior
+
+
+
+ The detach behavior has changed in several ways:
+
+
+
+ In the 1.x.x release, managed entities
+ were flushed to the database as part of the
+ detach operation. This is no longer done in
+ 2.0.
+
+
+
+
+ In the 1.x.x release, entities were copied
+ and returned. In 2.0, for those methods
+ that have return values, the original
+ entities are returned.
+
+
+
+
+ In the 1.x.x release, managed entities still
+ exist in the persistent context. In 2.0,
+ they are removed.
+
+
+
+
+ In the 1.x.x release, the detach operation
+ is recursively cascaded to all referenced
+ entities. In 2.0, the detach operation is
+ only cascaded to those entities for which
+ Cascade=detach has been specified.
+
+
+
+
+
+ Applications that use a 1.0 persistence.xml will
+ automatically maintain OpenJPA 1.x.x behavior. It is
+ possible for a version 2.0 application to revert back to
+ the 1.x.x behavior for some of these items by setting the
+ openjpa.Compatibility property as follows:
+
+ CopyOnDetach=true
+ FlushBeforeDetach=true
+ CascadeWithDetach=true
+
+
+
+ In addition, a new method has been provided on the
+
+ OpenJPAEntityManager
+ interface to return a copy of the entity:
+
+ public <T> T detachCopy(T pc):
+
+
+
+
+
+ Use of private persistent properties
+
+
+
+ In 1.x.x releases of OpenJPA, if property access was used,
+ private properties were considered persistent. This is
+ contrary to the JPA specification, which states that
+ persistent properties must be public or protected. In
+ OpenJPA 2.0 and later, private properties will not be
+ persistent by default.
+
+
+ Applications that use a 1.0 persistence.xml will
+ automatically maintain OpenJPA 1.x.x behavior. It is
+ possible for a version 2.0 application to revert back to
+ the 1.x.x behavior by setting the value of the
+ openjpa.Compatibility
+ property PrivatePersistentProperties to
+ true. If compile time enhancement is
+ used, this property must be specified at the time of
+ enhancement and at runtime.
+
+
+
+
+ Query.setParameter()
+
+
+
+ The Query interface setParameter() method behavior has
+ changed to throw an IllegalArgumentException (as required
+ by the JPA specification) if more parameter substitutions
+ are supplied than defined in the createQuery(),
+ createNamedQuery(), or createNativeQuery() invocation.
+ OpenJPA 1.2.x and prior versions silently ignored these
+ extraneous parameter substitutions and allowed the Query
+ to be processed.
+
+
+
+
+ Serialization of Entities
+
+
+
+ In 1.x.x releases of OpenJPA, when an entity was serialized
+ after calling EntityManager.find(), detach() or detachAll()
+ then all
+ references were removed as expected, but when the same
+ entity instance was serialized after calling
+ EntityManager.clear() the proxy classes were not removed.
+
+
+ This has two side-effects:
+ when entities are remoted across JVM boundaries (RPC)
+ or deserialized the OpenJPA runtime must be available
+ on the classpath (both client and server containers);
+ when entities are deserialized the OpenJPA runtime must
+ be the exact same revision as used to serialize the
+ entities due to the proxy classes using dynamically
+ generated serialVersionUID values.
+
+
+ Starting with OpenJPA 2.0, this behavior has been
+ modified, so that by default all proxies will be removed
+ during serialization. See
+
+ on how the behavior changes based on the
+ DetachedStateField setting along with
+
+ for more details on how to override the default
+ DetachedStateField setting.
+
+
+ Applications that use a 1.0 persistence.xml will
+ automatically maintain the old behavior. It is
+ possible for a version 2.0 application to revert back to
+ the prior 1.x.x behavior by setting the following
+ openjpa.Compatibility property as follows:
+
+ IgnoreDetachedStateFieldForProxySerialization=true
+
+
+
+
+
+ openjpa.jdbc.QuerySQLCache
+
+
+
+ In prior 1.x.x releases, the openjpa.jdbc.QuerySQLCache
+ configuration property for Prepared SQL Cache accepted
+ value all to never drop items from the
+ cache, but this option is no longer supported and will cause
+ a PersistenceException with a root cause of a ParseException
+ to be thrown. See
+
+ for details on the available configuration values.
+
+
+
+
+
+ Disabling AutoOff Collection Tracking
+
+
+
+ The default behavior of OpenJPA in tracking collections is that
+ if the number of modifications to the collection exceeds the
+ current number of elements in collection then OpenJPA will
+ disable tracking the collections. OpenJPA 2.0 added a compatibility
+ property to disable turning off the collection tracking.
+
+
+ The behavior of Auto disabling of collection tracking can be
+ avoided by setting the value of the
+ openjpa.Compatibility property
+ autoOff to false.
+ The default behavior of auto disabling the collection tracking
+ is not changed. But when the above property is set then the
+ collection tracking will not be disabled automatically.
+
+
+
+
+ Internal Behavioral Differences
+
+
+ The following sections indicate internal changes between
+ OpenJPA 1.x.x releases and the 2.0 release. As these are
+ internal implementation specific behaviors not covered by
+ the JPA specification, no changes should be required for
+ applications that did not use or depend upon OpenJPA specific
+ APIs or behavior.
+
+
+
+
+ PreUpdate/PostUpdate Life Cycle Callbacks
+
+
+
+ If an entity was updated between the persist()
+ and commit() operations in OpenJPA 1.x, then
+ any PreUpdate and PostUpdate life cycle callback
+ methods would be executed. Starting in OpenJPA
+ 1.3 and 2.0, these callbacks will not get executed.
+
+
+ The JPA 2.0 specification section on "Semantics
+ of the Life Cycle Callback Methods for Entities"
+ has been updated to include a Note that the
+ callback behavior for updating an entity after
+ the persist operation is implementation specific
+ and should not be relied upon.
+
+
+
+
+ createEntityManagerFactory Exceptions
+
+
+
+ The JPA 2.0 specification section on
+ "Bootstrapping in Java SE Environments" states
+ that persistence providers must return null
+ if they are not a qualified provider for the
+ given persistence unit.
+
+
+ However, OpenJPA may throw a RuntimeException
+ if an error occurs while trying to create a
+ qualified persistence unit, like for invalid
+ openjpa.* specific configuration settings or
+ for schema validation failures.
+
+
+ If the Apache Geronimo JPA 2.0 Spec APIs are
+ used, then any exceptions returned by a
+ persistence provider will be wrapped within
+ a PersistenceException. When the JPA 2.0 API
+ reference implementation is used, any
+ RuntimeExceptions will be returned to the
+ calling application without being wrapped.
+ Other JPA 2.0 API and implementation providers
+ or versions may behave differently.
+
+
+
+
+ openjpa.QueryCache default
+
+
+
+ In previous releases, the default value for the
+ openjpa.QueryCache property was true
+ when the openjpa.DataCache was enabled. Depending on
+ application characteristics, this default QueryCache
+ enablement actually could negate much of the potential
+ gains achieved by using the DataCache. Thus, the default
+ value for the openjpa.QueryCache property is now
+ false.
+
+
+ To re-enable the default QueryCache behavior, you need to
+ include the following property in your persistence.xml
+ configuration.
+
+ <property name="openjpa.QueryCache" value="true"/>
+
+
+
+ If your configuration had previously enabled the QueryCache
+ explicitly, then you might have to include the
+ true value into your configuration
+ (if you relied on the previous default). Otherwise, your
+ current QueryCache enablement will continue to work.
+
+ <property name="openjpa.QueryCache" value="true(CacheSize=1000, SoftReferenceSize=100)"/>
+