# Migration Considerations

## 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)"/>

## 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

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.

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.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 `javax.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 `javax.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"/>