Miscellaneous cleanup and fixes. Some documentation review.

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@452243 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2006-10-02 22:22:18 +00:00
parent e30632b60b
commit bdae6535ec
47 changed files with 1878 additions and 3090 deletions

View File

@ -102,10 +102,7 @@ class PreparedStatementManagerImpl
} catch (SQLException se) {
throw SQLExceptions.getStore(se, row.getFailedObject(), _dict);
} finally {
try {
stmnt.close();
} catch (SQLException se) {
}
try { stmnt.close(); } catch (SQLException se) {}
}
// set auto assign values

View File

@ -60,8 +60,7 @@ public class DataSourceFactory {
*/
public static DataSource newDataSource(JDBCConfiguration conf,
boolean factory2) {
String driver = (factory2)
? conf.getConnection2DriverName()
String driver = (factory2) ? conf.getConnection2DriverName()
: conf.getConnectionDriverName();
if (driver == null || driver.length() == 0)
throw new UserException(_loc.get("no-driver", driver)).
@ -69,12 +68,10 @@ public class DataSourceFactory {
ClassLoader loader = conf.getClassResolverInstance().
getClassLoader(DataSourceFactory.class, null);
String props = (factory2)
? conf.getConnection2Properties()
String props = (factory2) ? conf.getConnection2Properties()
: conf.getConnectionProperties();
try {
Class driverClass;
try {
driverClass = Class.forName(driver, true, loader);
} catch (ClassNotFoundException cnfe) {
@ -86,25 +83,23 @@ public class DataSourceFactory {
DriverDataSource ds = conf.newDriverDataSourceInstance();
ds.setClassLoader(loader);
ds.setConnectionDriverName(driver);
ds.setConnectionProperties
(Configurations.parseProperties(props));
ds.setConnectionProperties(Configurations.
parseProperties(props));
if (!factory2) {
ds.setConnectionFactoryProperties
(Configurations.parseProperties
(conf.getConnectionFactoryProperties()));
ds.setConnectionFactoryProperties(Configurations.
parseProperties(conf.getConnectionFactoryProperties()));
ds.setConnectionURL(conf.getConnectionURL());
ds.setConnectionUserName(conf.getConnectionUserName());
ds.setConnectionPassword(conf.getConnectionPassword());
} else {
ds.setConnectionFactoryProperties
(Configurations.parseProperties
(conf.getConnectionFactory2Properties()));
(Configurations.parseProperties(conf.
getConnectionFactory2Properties()));
ds.setConnectionURL(conf.getConnection2URL());
ds.setConnectionUserName(conf.getConnection2UserName());
ds.setConnectionPassword(conf.getConnection2Password());
}
return ds;
}
@ -121,8 +116,7 @@ public class DataSourceFactory {
}
// not a driver or a data source; die
throw new UserException(_loc.get("bad-driver", driver)).
setFatal(true);
throw new UserException(_loc.get("bad-driver", driver)).setFatal(true);
}
/**
@ -186,7 +180,6 @@ public class DataSourceFactory {
DecoratingDataSource ds, final JDBCConfiguration conf,
boolean factory2) {
DataSource inner = ds.getInnermostDelegate();
if (inner instanceof DriverDataSource)
((DriverDataSource) inner).initDBDictionary(dict);
@ -204,8 +197,7 @@ public class DataSourceFactory {
// transaction isolation, etc)
ConfiguringConnectionDecorator ccd =
new ConfiguringConnectionDecorator();
ccd.setTransactionIsolation
(conf.getTransactionIsolationConstant());
ccd.setTransactionIsolation(conf.getTransactionIsolationConstant());
if (factory2 || !conf.isConnectionFactoryModeManaged()) {
if (!dict.supportsMultipleNontransactionalResultSets)
ccd.setAutoCommit(Boolean.FALSE);

View File

@ -20,7 +20,6 @@ import java.util.Properties;
import javax.sql.DataSource;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.conf.Configurable;
/**
* A DataSource that allows additional configuration options to be set
@ -29,7 +28,7 @@ import org.apache.openjpa.lib.conf.Configurable;
* @author Marc Prud'hommeaux
*/
public interface DriverDataSource
extends DataSource, Configurable {
extends DataSource {
public void setConnectionURL(String connectionURL);

View File

@ -25,10 +25,15 @@ import java.util.Properties;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.util.StoreException;
/**
* Non-pooling driver data source.
*/
public class SimpleDriverDataSource
implements DriverDataSource {
implements DriverDataSource, Configurable {
private String _connectionDriverName;
private String _connectionURL;
@ -40,38 +45,6 @@ public class SimpleDriverDataSource
private Driver _driver;
private ClassLoader _classLoader;
private synchronized Driver getDriver()
throws SQLException {
if (_driver == null)
_driver = DriverManager.getDriver(_connectionURL);
if (_driver == null) {
try {
Class.forName(_connectionDriverName, true, _classLoader);
} catch (Exception e) {
}
_driver = DriverManager.getDriver(_connectionURL);
}
if (_driver == null) {
try {
_driver = (Driver) Class.forName(_connectionDriverName,
true, _classLoader).newInstance();
} catch (Exception e) {
if (e instanceof SQLException)
throw(SQLException) e;
if (e instanceof RuntimeException)
throw(RuntimeException) e;
throw new SQLException(e.getClass() + ": " + e.getMessage());
}
}
return _driver;
}
public Connection getConnection()
throws SQLException {
return getConnection(null);
@ -80,16 +53,13 @@ public class SimpleDriverDataSource
public Connection getConnection(String username, String password)
throws SQLException {
Properties props = new Properties();
if (username == null)
username = _connectionUserName;
if (username != null)
props.put("user", username);
if (password == null)
password = _connectionPassword;
if (password != null)
props.put("password", password);
@ -98,7 +68,7 @@ public class SimpleDriverDataSource
public Connection getConnection(Properties props)
throws SQLException {
return getDriver().connect(_conf.getConnectionURL(), props);
return _driver.connect(_conf.getConnectionURL(), props);
}
public int getLoginTimeout() {
@ -115,14 +85,31 @@ public class SimpleDriverDataSource
public void setLogWriter(PrintWriter out) {
}
public void setConfiguration(Configuration conf) {
_conf = (JDBCConfiguration) conf;
}
public void startConfiguration() {
}
public void endConfiguration() {
}
public void setConfiguration(Configuration conf) {
_conf = (JDBCConfiguration) conf;
try {
_driver = DriverManager.getDriver(_connectionURL);
if (_driver == null) {
try {
Class.forName(_connectionDriverName, true, _classLoader);
} catch (Exception e) {
}
_driver = DriverManager.getDriver(_connectionURL);
}
if (_driver == null)
_driver = (Driver) Class.forName(_connectionDriverName,
true, _classLoader).newInstance();
} catch (Exception e) {
if (e instanceof RuntimeException)
throw(RuntimeException) e;
throw new StoreException(e);
}
}
public void initDBDictionary(DBDictionary dict) {

View File

@ -202,8 +202,6 @@ abstract class AttachStrategy
break;
case JavaTypes.COLLECTION:
Collection frmc = (Collection) fetchObjectField(i);
System.out.println("Fetch:" + fmd + ":" + frmc
+ ":" + nullLoaded);
if (frmc == null && !nullLoaded)
return false;
Collection toc = (Collection) sm.fetchObjectField(i);

View File

@ -1233,10 +1233,7 @@ public class BrokerImpl
catch (RuntimeException re) {
if (!rollback) {
forcedRollback = true;
try {
_store.rollback();
} catch (RuntimeException re2) {
}
try { _store.rollback(); } catch (RuntimeException re2) {}
}
err = re;
} finally {
@ -3794,8 +3791,7 @@ public class BrokerImpl
_transAdditions = new HashSet();
_transAdditions.add(sm);
}
}
finally {
} finally {
unlock();
}
}

View File

@ -250,22 +250,22 @@ class SingleFieldManager
case JavaTypes.PC_UNTYPED:
if (!_broker.isDetachedNew() && _broker.isDetached(objval))
return; // allow but ignore
_broker.persist(objval, false, call);
_broker.persist(objval, true, call);
break;
case JavaTypes.ARRAY:
_broker.persistAll(Arrays.asList((Object[]) objval), false,
_broker.persistAll(Arrays.asList((Object[]) objval), true,
call);
break;
case JavaTypes.COLLECTION:
_broker.persistAll((Collection) objval, false, call);
_broker.persistAll((Collection) objval, true, call);
break;
case JavaTypes.MAP:
if (fmd.getKey().getCascadePersist()
== ValueMetaData.CASCADE_IMMEDIATE)
_broker.persistAll(((Map) objval).keySet(), false, call);
_broker.persistAll(((Map) objval).keySet(), true, call);
if (fmd.getElement().getCascadePersist()
== ValueMetaData.CASCADE_IMMEDIATE)
_broker.persistAll(((Map) objval).values(), false, call);
_broker.persistAll(((Map) objval).values(), true, call);
break;
}
}
@ -615,8 +615,8 @@ class SingleFieldManager
if (external)
val = fmd.getExternalValue(val, _broker);
else if (val instanceof Proxy) {
// shortcut change trackers; also ensures we don't iterate
// lrs fields
// shortcut change trackers; also ensures we don't
// iterate lrs fields
ChangeTracker ct = ((Proxy) val).getChangeTracker();
if (ct != null && ct.isTracking()) {
preFlushPCs(fmd.getElement(), ct.getAdded(),
@ -646,8 +646,8 @@ class SingleFieldManager
val = fmd.getExternalValue(val, _broker);
external = false;
} else if (val instanceof Proxy) {
// shortcut change trackers; also ensures we don't iterate
// lrs fields
// shortcut change trackers; also ensures we don't
// iterate lrs fields
MapChangeTracker ct = (MapChangeTracker) ((Proxy) val).
getChangeTracker();
if (ct != null && ct.isTracking() && ct.getTrackKeys())
@ -670,8 +670,8 @@ class SingleFieldManager
if (external)
val = fmd.getExternalValue(val, _broker);
else if (val instanceof Proxy) {
// shortcut change trackers; also ensures we don't iterate
// lrs fields
// shortcut change trackers; also ensures we don't
// iterate lrs fields
MapChangeTracker ct = (MapChangeTracker) ((Proxy) val).
getChangeTracker();
if (ct != null && ct.isTracking()) {
@ -743,10 +743,9 @@ class SingleFieldManager
sm = _broker.getStateManager(obj);
if (sm == null || !sm.isPersistent())
throw new InvalidStateException
(_loc.get("cant-cascade-persist",
Exceptions.toString(obj), vmd,
Exceptions.toString(_sm.getManagedInstance()))).
throw new InvalidStateException(_loc.get("cant-cascade-persist",
Exceptions.toString(obj), vmd,
Exceptions.toString(_sm.getManagedInstance()))).
setFailedObject(obj);
} else {
sm = _broker.getStateManager(obj);
@ -763,8 +762,9 @@ class SingleFieldManager
Exceptions.toString(_sm.getManagedInstance()))).
setFailedObject(obj);
((StateManagerImpl) sm).nonprovisional(logical, call);
((StateManagerImpl) sm).setDereferencedDependent(false, true);
StateManagerImpl smimpl = (StateManagerImpl) sm;
smimpl.nonprovisional(logical, call);
smimpl.setDereferencedDependent(false, true);
}
}

View File

@ -486,8 +486,8 @@ public class StateManagerImpl
* @param recache whether to recache ourself on the new oid
*/
private void assertObjectIdAssigned(boolean recache) {
if (!isNew() || isDeleted() || isProvisional() ||
(_flags & FLAG_OID_ASSIGNED) > 0)
if (!isNew() || isDeleted() || isProvisional()
|| (_flags & FLAG_OID_ASSIGNED) != 0)
return;
if (_oid == null) {
if (_meta.getIdentityType() == ClassMetaData.ID_DATASTORE)

View File

@ -340,8 +340,7 @@ public class MetaDataRepository
classList.add(cls);
break;
}
}
catch (Throwable t) {
} catch (Throwable t) {
// this happens when the class is not loadable by
// the environment class loader, so it was probably
// listed elsewhere; also ignore linkage failures and
@ -364,8 +363,7 @@ public class MetaDataRepository
if (!mustExist)
return null;
throw new MetaDataException(_loc.get("no-alias-meta", alias,
_aliases));
throw new MetaDataException(_loc.get("no-alias-meta", alias, _aliases));
}
/**
@ -408,8 +406,7 @@ public class MetaDataRepository
// class never registers itself with the system
if ((_validate & VALIDATE_RUNTIME) != 0) {
try {
Class.forName(cls.getName(), true,
cls.getClassLoader());
Class.forName(cls.getName(), true, cls.getClassLoader());
} catch (Throwable t) {
}
}

View File

@ -74,6 +74,7 @@ tcp-close-sending-socket: Closing transmission connection to "{0}" that was \
tcp-close-pool-error: Exception thrown while closing connection pool.
tcp-wrong-version-error: Received packet from "{0}" with invalid version \
number. Check if a prior release of OpenJPA is being used on this host.
bean-constructor: Could not instantiate class {0}.
bean-constructor: Could not instantiate class {0}. Make sure it has an \
accessible no-args constructor.
method-notfound: Method "{1}" with arguments of type: {2} \
not found in class "{0}".

View File

@ -84,7 +84,6 @@ import org.apache.openjpa.kernel.jpql.JPQLParser;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Localizer.Message;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.DelegatingMetaDataFactory;
import org.apache.openjpa.meta.FieldMetaData;
@ -580,14 +579,14 @@ public class AnnotationPersistenceMetaDataParser
highs[i] = listeners[i].size();
}
recordCallbacks(meta, parseCallbackMethods(_cls, listeners, false,
false), highs, false);
false, getRepository()), highs, false);
// scan possibly non-PC hierarchy for callbacks.
// redundant for PC superclass but we don't know that yet
// so let LifecycleMetaData determine that
if (!Object.class.equals(_cls.getSuperclass())) {
recordCallbacks(meta, parseCallbackMethods(_cls.
getSuperclass(), null, true, false), null, true);
recordCallbacks(meta, parseCallbackMethods(_cls.getSuperclass(),
null, true, false, getRepository()), null, true);
}
}
@ -759,7 +758,8 @@ public class AnnotationPersistenceMetaDataParser
Class[] classes = listeners.value();
Collection<LifecycleCallbacks>[] parsed = null;
for (Class cls : classes)
parsed = parseCallbackMethods(cls, parsed, true, true);
parsed = parseCallbackMethods(cls, parsed, true, true,
getRepository());
return parsed;
}
@ -771,9 +771,9 @@ public class AnnotationPersistenceMetaDataParser
* @param sups whether to scan superclasses
* @param listener whether this is a listener or not
*/
public Collection<LifecycleCallbacks>[] parseCallbackMethods
public static Collection<LifecycleCallbacks>[] parseCallbackMethods
(Class cls, Collection<LifecycleCallbacks>[] callbacks, boolean sups,
boolean listener) {
boolean listener, MetaDataRepository repos) {
// first sort / filter based on inheritance
Set<Method> methods = new TreeSet<Method>(MethodComparator.
getInstance());
@ -796,16 +796,15 @@ public class AnnotationPersistenceMetaDataParser
}
}
sup = sup.getSuperclass();
}
while (sups && !Object.class.equals(sup));
} while (sups && !Object.class.equals(sup));
MetaDataDefaults def = repos.getMetaDataFactory().getDefaults();
for (Method m : methods) {
for (Annotation anno : m.getDeclaredAnnotations()) {
MetaDataTag tag = _tags.get(anno.annotationType());
if (tag == null)
continue;
int[] events = XMLPersistenceMetaDataParser.getEventTypes(tag);
int[] events = MetaDataParsers.getEventTypes(tag);
if (events == null)
continue;
@ -813,18 +812,13 @@ public class AnnotationPersistenceMetaDataParser
callbacks = (Collection<LifecycleCallbacks>[])
new Collection[LifecycleEvent.ALL_EVENTS.length];
for (int i = 0; events != null && i < events.length; i++) {
for (int i = 0; i < events.length; i++) {
int e = events[i];
if (!verifyHasNoArgConstructor(cls))
continue;
if (!verifyMultipleMethodsOnSameEvent(cls, callbacks[e], m,
tag))
continue;
if (callbacks[e] == null)
callbacks[e] = new ArrayList(3);
callbacks[e] = new ArrayList(3);
if (listener) {
MetaDataParsers.validateMethodsForSameCallback(cls,
callbacks[e], m, tag, def, repos.getLog());
callbacks[e].add(new BeanLifecycleCallbacks(cls, m,
false));
} else {
@ -836,58 +830,6 @@ public class AnnotationPersistenceMetaDataParser
}
return callbacks;
}
private boolean verifyMultipleMethodsOnSameEvent(Class cls,
Collection<LifecycleCallbacks> callbacks, Method method,
MetaDataTag tag) {
boolean result = true;
if (callbacks == null || callbacks.isEmpty())
return true;
for (LifecycleCallbacks lc: callbacks) {
if (!(lc instanceof MethodLifecycleCallbacks))
continue;
Method exists = ((MethodLifecycleCallbacks)lc).getCallbackMethod();
if (exists.getDeclaringClass().equals(method.getDeclaringClass())) {
result = false;
Object[] args = new Object[]{method.getDeclaringClass()
.getName(), method.getName(), exists.getName(),
tag.toString()};
PersistenceMetaDataDefaults defaults = getDefaults();
if (defaults == null ||
defaults.getAllowsMultipleMethodsOnSameCallback()) {
_log.warn(_loc.get("multiple-methods-on-callback", args));
} else {
throw new UserException(
_loc.get("multiple-methods-on-callback-error", args));
}
}
}
return result;
}
private boolean verifyHasNoArgConstructor(Class cls) {
try {
cls.getConstructor(new Class[]{});
return true;
} catch (Throwable t) {
PersistenceMetaDataDefaults defaults = getDefaults();
Message msg = _loc.get("missing-no-arg-constructor", cls.getName());
if (defaults == null ||
defaults.getAllowsMissingCallbackConstructor())
_log.warn(msg);
else
throw new UserException(msg, t);
}
return false;
}
private PersistenceMetaDataDefaults getDefaults() {
MetaDataDefaults defaults = getRepository().getMetaDataFactory().
getDefaults();
if (defaults instanceof PersistenceMetaDataDefaults)
return (PersistenceMetaDataDefaults)defaults;
return null;
}
/**
* Store lifecycle metadata.

View File

@ -0,0 +1,88 @@
package org.apache.openjpa.persistence;
import java.lang.reflect.Method;
import java.util.Collection;
import org.apache.openjpa.event.LifecycleCallbacks;
import org.apache.openjpa.event.LifecycleEvent;
import org.apache.openjpa.event.MethodLifecycleCallbacks;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.MetaDataDefaults;
import org.apache.openjpa.util.UserException;
/**
* Common utilities for persistence metadata parsers.
*
* @author Abe White
*/
class MetaDataParsers {
private static final Localizer _loc = Localizer.forPackage
(MetaDataParsers.class);
/**
* Return the event type constants for the given tag, or null if none.
*/
public static int[] getEventTypes(MetaDataTag tag) {
switch (tag) {
case PRE_PERSIST:
return new int[]{ LifecycleEvent.BEFORE_PERSIST };
case POST_PERSIST:
return new int[]{ LifecycleEvent.AFTER_PERSIST };
case PRE_REMOVE:
return new int[]{ LifecycleEvent.BEFORE_DELETE };
case POST_REMOVE:
return new int[]{ LifecycleEvent.AFTER_DELETE };
case PRE_UPDATE:
return new int[]{ LifecycleEvent.BEFORE_STORE };
case POST_UPDATE:
return new int[]{ LifecycleEvent.AFTER_STORE };
case POST_LOAD:
return new int[]{ LifecycleEvent.AFTER_LOAD,
LifecycleEvent.AFTER_REFRESH };
default:
return null;
}
}
/**
* Validate that the given listener class does not have multiple methods
* listening for the same lifecycle event, which is forbidden by the spec.
*/
public static void validateMethodsForSameCallback(Class cls,
Collection<LifecycleCallbacks> callbacks, Method method,
MetaDataTag tag, MetaDataDefaults def, Log log) {
if (callbacks == null || callbacks.isEmpty())
return;
for (LifecycleCallbacks lc: callbacks) {
if (!(lc instanceof MethodLifecycleCallbacks))
continue;
Method exists = ((MethodLifecycleCallbacks)lc).getCallbackMethod();
if (!exists.getDeclaringClass().equals(method.getDeclaringClass()))
continue;
PersistenceMetaDataDefaults defaults = getPersistenceDefaults(def);
Localizer.Message msg = _loc.get("multiple-methods-on-callback",
new Object[] { method.getDeclaringClass().getName(),
method.getName(), exists.getName(), tag.toString() });
if (defaults == null
|| defaults.getAllowsMultipleMethodsForSameCallback())
log.warn(msg);
else
throw new UserException(msg);
}
}
/**
* Return the {@link PersistenceMetaDataDefaults} in use, or null if not
* using JPA defaults.
*/
private static PersistenceMetaDataDefaults getPersistenceDefaults
(MetaDataDefaults def) {
if (def instanceof PersistenceMetaDataDefaults)
return (PersistenceMetaDataDefaults) def;
return null;
}
}

View File

@ -78,10 +78,10 @@ public interface OpenJPAEntityManagerFactory
* settings. OpenJPA recognizes the following configuration settings in this
* method:
* <ul>
* <li>org.apache.openjpa.ConnectionUsername</li>
* <li>org.apache.openjpa.ConnectionPassword</li>
* <li>org.apache.openjpa.ConnectionRetainMode</li>
* <li>org.apache.openjpa.TransactionMode</li>
* <li>openjpa.ConnectionUsername</li>
* <li>openjpa.ConnectionPassword</li>
* <li>openjpa.ConnectionRetainMode</li>
* <li>openjpa.TransactionMode</li>
* </ul>
*/
public OpenJPAEntityManager createEntityManager(Map props);
@ -90,7 +90,8 @@ public interface OpenJPAEntityManagerFactory
* Register a listener for lifecycle-related events on the specified
* classes. If the classes are null, all events will be propagated to
* the listener. The listener will be passed on to all new entity
* managers. See the <code>org.apache.openjpa.event</code> package for listener types.
* managers. See the <code>org.apache.openjpa.event</code> package for
* listener types.
*
* @since 0.3.3
*/

View File

@ -53,17 +53,15 @@ import static org.apache.openjpa.persistence.PersistenceStrategy.*;
import org.apache.openjpa.util.MetaDataException;
/**
* Javax persistence-based metadata defaults.
* JPA-based metadata defaults.
*
* @author Patrick Linskey
* @author Abe White
* @nojavadoc
*/
public class PersistenceMetaDataDefaults
extends AbstractMetaDataDefaults {
private boolean _allowsMultipleMethodsOnSameCallback;
private boolean _allowsMissingCallbackConstructor;
private boolean _allowsMultipleMethodsForSameCallback = true;
private static Localizer _loc = Localizer.forPackage
(PersistenceMetaDataDefaults.class);
@ -97,8 +95,6 @@ public class PersistenceMetaDataDefaults
public PersistenceMetaDataDefaults() {
setCallbackMode(CALLBACK_RETHROW | CALLBACK_ROLLBACK |
CALLBACK_FAIL_FAST);
_allowsMultipleMethodsOnSameCallback = true;
_allowsMissingCallbackConstructor = true;
}
/**
@ -182,6 +178,35 @@ public class PersistenceMetaDataDefaults
return BASIC;
return null;
}
/**
* Flags if multiple methods of the same class can handle the same
* callback event.
*/
public boolean getAllowsMultipleMethodsForSameCallback() {
return _allowsMultipleMethodsForSameCallback;
}
/**
* Flags if multiple methods of the same class can handle the same
* callback event.
*/
public void setAllowsMultipleMethodsForSameCallback(boolean flag) {
_allowsMultipleMethodsForSameCallback = flag;
}
/**
* Auto-configuration method for the default access type of base classes
* with ACCESS_UNKNOWN
*/
public void setDefaultAccessType(String type) {
if (type == null)
return;
if ("PROPERTY".equals(type.toUpperCase()))
setDefaultAccessType(ClassMetaData.ACCESS_PROPERTY);
else
setDefaultAccessType(ClassMetaData.ACCESS_FIELD);
}
@Override
public void populate(ClassMetaData meta, int access) {
@ -271,31 +296,4 @@ public class PersistenceMetaDataDefaults
return false;
return true;
}
/**
* Flags if multiple methods of the same class can handle the same
* callback event.
*/
public boolean getAllowsMultipleMethodsOnSameCallback() {
return _allowsMultipleMethodsOnSameCallback;
}
public void setAllowsMultipleMethodsOnSameCallback(boolean flag) {
_allowsMultipleMethodsOnSameCallback = flag;
}
/**
* Flags if it allowed for the callback listener class not to have a no-arg
* constructor.
*/
public boolean getAllowsMissingCallbackConstructor() {
return _allowsMissingCallbackConstructor;
}
public void setAllowsMissingCallbackConstructor(boolean flag) {
_allowsMissingCallbackConstructor = flag;
}
}

View File

@ -35,11 +35,13 @@ import javax.persistence.NamedNativeQuery;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.GenericConfigurable;
import org.apache.openjpa.lib.meta.ClassAnnotationMetaDataFilter;
import org.apache.openjpa.lib.meta.ClassArgParser;
import org.apache.openjpa.lib.meta.MetaDataFilter;
import org.apache.openjpa.lib.meta.MetaDataParser;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.AbstractCFMetaDataFactory;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
@ -58,18 +60,18 @@ import org.apache.openjpa.util.MetaDataException;
*/
public class PersistenceMetaDataFactory
extends AbstractCFMetaDataFactory
implements Configurable {
implements Configurable, GenericConfigurable {
private static final Localizer _loc = Localizer.forPackage
(PersistenceMetaDataFactory.class);
private final PersistenceMetaDataDefaults _def =
new PersistenceMetaDataDefaults();
private AnnotationPersistenceMetaDataParser _annoParser = null;
private XMLPersistenceMetaDataParser _xmlParser = null;
private PersistenceMetaDataDefaults _def = null;
private Map<URL, Set> _xml = null; // xml rsrc -> class names
private Set<URL> _unparsed = null; // xml rsrc
private boolean _fieldOverride = true;
private int _access = ClassMetaData.ACCESS_FIELD;
/**
* Whether to use field-level override or class-level override.
@ -87,18 +89,6 @@ public class PersistenceMetaDataFactory
return _fieldOverride;
}
/**
* The default access type for base classes with ACCESS_UNKNOWN
*/
public void setDefaultAccessType(String type) {
if (type == null)
return;
if ("PROPERTY".equals(type.toUpperCase()))
_access = ClassMetaData.ACCESS_PROPERTY;
else
_access = ClassMetaData.ACCESS_FIELD;
}
/**
* Return metadata parser, creating it if it does not already exist.
*/
@ -333,10 +323,6 @@ public class PersistenceMetaDataFactory
}
public MetaDataDefaults getDefaults() {
if (_def == null) {
_def = new PersistenceMetaDataDefaults();
_def.setDefaultAccessType(_access);
}
return _def;
}
@ -415,4 +401,8 @@ public class PersistenceMetaDataFactory
else
rsrcs.add ("META-INF/orm.xml");
}
public void setInto(Options opts) {
opts.keySet().retainAll(opts.setInto(_def).keySet());
}
}

View File

@ -113,9 +113,10 @@ public class PersistenceProductDerivation
throws IOException {
if (pinfo == null)
return null;
if (!isOpenJPAPersistenceProvider(pinfo, null))
if (!isOpenJPAPersistenceProvider(pinfo, null)) {
warnUnknownProvider(pinfo);
return null;
}
ConfigurationProviderImpl cp = new ConfigurationProviderImpl();
cp.addProperties(PersistenceUnitInfoImpl.toOpenJPAProperties(pinfo));
@ -148,8 +149,10 @@ public class PersistenceProductDerivation
// persistence.xml does not exist; just load map
PersistenceUnitInfoImpl pinfo = new PersistenceUnitInfoImpl();
pinfo.fromUserProperties(m);
if (!isOpenJPAPersistenceProvider(pinfo, null))
if (!isOpenJPAPersistenceProvider(pinfo, null)) {
warnUnknownProvider(pinfo);
return null;
}
cp.addProperties(pinfo.toOpenJPAProperties());
return cp;
}
@ -248,8 +251,10 @@ public class PersistenceProductDerivation
rsrc, String.valueOf(name)).getMessage(), getClass().getName(),
rsrc);
} else if (!isOpenJPAPersistenceProvider(pinfo, loader)) {
if (!explicit)
if (!explicit) {
warnUnknownProvider(pinfo);
return Boolean.FALSE;
}
throw new MissingResourceException(_loc.get("unknown-provider",
rsrc, name, pinfo.getPersistenceProviderClassName()).
getMessage(), getClass().getName(), rsrc);
@ -319,20 +324,30 @@ public class PersistenceProductDerivation
try {
if (PersistenceProviderImpl.class.isAssignableFrom
(Class.forName(provider, false, loader))) {
// log not configured yet
warn(_loc.get("extended-provider", provider).getMessage());
log(_loc.get("extended-provider", provider).getMessage());
return true;
}
} catch (Throwable t) {
warn(_loc.get("unloadable-provider", provider, t).
getMessage());
log(_loc.get("unloadable-provider", provider, t).getMessage());
return false;
}
warn(_loc.get("unrecognized-provider", provider).getMessage());
return false;
}
/**
* Warn the user that we could only find an unrecognized persistence
* provider.
*/
private static void warnUnknownProvider(PersistenceUnitInfo pinfo) {
log(_loc.get("unrecognized-provider",
pinfo.getPersistenceProviderClassName()).getMessage());
}
private static void warn(String msg) {
/**
* Log a message.
*/
private static void log(String msg) {
// at this point logging isn't configured yet
System.err.println(msg);
}

View File

@ -48,6 +48,7 @@ import org.apache.openjpa.meta.DelegatingMetaDataFactory;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.LifecycleMetaData;
import org.apache.openjpa.meta.MetaDataDefaults;
import org.apache.openjpa.meta.MetaDataFactory;
import static org.apache.openjpa.meta.MetaDataModes.*;
import org.apache.openjpa.meta.MetaDataRepository;
@ -196,8 +197,7 @@ public class XMLPersistenceMetaDataParser
* The annotation parser. When class is discovered in an XML file,
* we first parse any annotations present, then override with the XML.
*/
public void setAnnotationParser(
AnnotationPersistenceMetaDataParser parser) {
public void setAnnotationParser(AnnotationPersistenceMetaDataParser parser){
_parser = parser;
}
@ -588,9 +588,10 @@ public class XMLPersistenceMetaDataParser
warnUnsupportedTag(name);
}
} else if (tag instanceof PersistenceStrategy) {
ret = startStrategy((PersistenceStrategy) tag, attrs);
PersistenceStrategy ps = (PersistenceStrategy) tag;
ret = startStrategy(ps, attrs);
if (ret)
_strategy = (PersistenceStrategy) tag;
_strategy = ps;
} else if (tag == ELEM_LISTENER)
ret = startEntityListener(attrs);
else if (tag == ELEM_ATTRS)
@ -819,8 +820,7 @@ public class XMLPersistenceMetaDataParser
if (log.isInfoEnabled())
log.info(_loc.get("parse-sequence", name));
SequenceMetaData meta = getRepository().getCachedSequenceMetaData
(name);
SequenceMetaData meta = getRepository().getCachedSequenceMetaData(name);
if (meta != null && log.isWarnEnabled())
log.warn(_loc.get("override-sequence", name));
@ -835,8 +835,7 @@ public class XMLPersistenceMetaDataParser
if (seq == null || seq.indexOf('(') == -1) {
clsName = SequenceMetaData.IMPL_NATIVE;
props = null;
} else // plugin
{
} else { // plugin
clsName = Configurations.getClassName(seq);
props = Configurations.getProperties(seq);
seq = null;
@ -1075,8 +1074,7 @@ public class XMLPersistenceMetaDataParser
field = meta.addDeclaredField(name, type);
PersistenceMetaDataDefaults.setCascadeNone(field);
PersistenceMetaDataDefaults.setCascadeNone(field.getKey());
PersistenceMetaDataDefaults.setCascadeNone
(field.getElement());
PersistenceMetaDataDefaults.setCascadeNone(field.getElement());
}
field.backingMember(member);
} else if (field == null) {
@ -1342,8 +1340,7 @@ public class XMLPersistenceMetaDataParser
if (log.isInfoEnabled())
log.info(_loc.get("parse-query", name));
QueryMetaData meta = getRepository().getCachedQueryMetaData
(null, name);
QueryMetaData meta = getRepository().getCachedQueryMetaData(null, name);
if (meta != null && log.isWarnEnabled())
log.warn(_loc.get("override-query", name, currentLocation()));
@ -1398,8 +1395,7 @@ public class XMLPersistenceMetaDataParser
if (log.isInfoEnabled())
log.info(_loc.get("parse-native-query", name));
QueryMetaData meta = getRepository().getCachedQueryMetaData
(null, name);
QueryMetaData meta = getRepository().getCachedQueryMetaData(null, name);
if (meta != null && log.isWarnEnabled())
log.warn(_loc.get("override-query", name, currentLocation()));
@ -1486,8 +1482,8 @@ public class XMLPersistenceMetaDataParser
_listener = classForName(attrs.getValue("class"));
boolean system = currentElement() == null;
Collection<LifecycleCallbacks>[] parsed =
new AnnotationPersistenceMetaDataParser(_conf).parseCallbackMethods
(_listener, null, true, true);
AnnotationPersistenceMetaDataParser.parseCallbackMethods(_listener,
null, true, true, _repos);
if (parsed == null)
return true;
@ -1526,8 +1522,11 @@ public class XMLPersistenceMetaDataParser
throws SAXException {
if (!isMetaDataMode())
return false;
boolean system = currentElement() == null;
int[] events = MetaDataParsers.getEventTypes(callback);
if (events == null)
return false;
boolean system = currentElement() == null;
Class type = currentElement() == null ? null :
((ClassMetaData) currentElement()).getDescribedType();
if (type == null)
@ -1540,6 +1539,7 @@ public class XMLPersistenceMetaDataParser
_highs = new int[LifecycleEvent.ALL_EVENTS.length];
}
MetaDataDefaults def = _repos.getMetaDataFactory().getDefaults();
LifecycleCallbacks adapter;
if (_listener != null)
adapter = new BeanLifecycleCallbacks(_listener,
@ -1548,12 +1548,13 @@ public class XMLPersistenceMetaDataParser
adapter = new MethodLifecycleCallbacks(_cls,
attrs.getValue("method-name"), false);
int[] events = getEventTypes(callback);
if (events == null)
return true;
for (int i = 0; i < events.length; i++) {
int event = events[i];
if (_listener != null) {
MetaDataParsers.validateMethodsForSameCallback(_listener,
_callbacks[event], ((BeanLifecycleCallbacks) adapter).
getCallbackMethod(), callback, def, getLog());
}
if (_callbacks[event] == null)
_callbacks[event] = new ArrayList<LifecycleCallbacks>(3);
_callbacks[event].add(adapter);
@ -1563,28 +1564,6 @@ public class XMLPersistenceMetaDataParser
return true;
}
static int[] getEventTypes(MetaDataTag tag) {
switch (tag) {
case PRE_PERSIST:
return new int[]{ LifecycleEvent.BEFORE_PERSIST };
case POST_PERSIST:
return new int[]{ LifecycleEvent.AFTER_PERSIST };
case PRE_REMOVE:
return new int[]{ LifecycleEvent.BEFORE_DELETE };
case POST_REMOVE:
return new int[]{ LifecycleEvent.AFTER_DELETE };
case PRE_UPDATE:
return new int[]{ LifecycleEvent.BEFORE_STORE };
case POST_UPDATE:
return new int[]{ LifecycleEvent.AFTER_STORE };
case POST_LOAD:
return new int[]{ LifecycleEvent.AFTER_LOAD,
LifecycleEvent.AFTER_REFRESH };
default:
return null;
}
}
/**
* Store lifecycle metadata.
*/
@ -1593,8 +1572,8 @@ public class XMLPersistenceMetaDataParser
Class supCls = cls.getDescribedType().getSuperclass();
Collection<LifecycleCallbacks>[] supCalls = null;
if (!Object.class.equals(supCls)) {
supCalls = new AnnotationPersistenceMetaDataParser(_conf).
parseCallbackMethods(supCls, null, true, false);
supCalls = AnnotationPersistenceMetaDataParser.parseCallbackMethods
(supCls, null, true, false, _repos);
}
if (supCalls != null) {
for (int event : LifecycleEvent.ALL_EVENTS) {
@ -1622,11 +1601,10 @@ public class XMLPersistenceMetaDataParser
/**
* Instantiate the given class, taking into account the default package.
*/
protected Class classForName (String name)
throws SAXException
{
if ("Entity".equals (name))
protected Class classForName(String name)
throws SAXException {
if ("Entity".equals(name))
return PersistenceCapable.class;
return super.classForName (name, isRuntime ());
return super.classForName(name, isRuntime());
}
}

View File

@ -60,7 +60,7 @@ missing-xml-config: The specified XML resource "{0}" for persistence unit \
"{1}" can''t be found in your class path.
cantload-xml-config: The specified XML resource "{0}" for persistence unit \
"{1}" can''t be parsed.
unknown-provider: Persistence Provider "{2}" specified in persistence unit \
unknown-provider: Persistence provider "{2}" specified in persistence unit \
"{1}" in "{0}" is not a recognized provider.
illegal-index: The parameter index {0} is invalid. Parameters must be \
integers starting at 1.
@ -86,19 +86,11 @@ system-listener-err: An error occurred invoking system entity listener \
no-transaction: Cannot perform operation with no transaction.
multiple-methods-on-callback: Class "{0}" declares method "{1}" as well \
as "{2}" for handling the same "{3}" callback.
multiple-methods-on-callback-error: Class "{0}" declares method "{1}" as well \
as "{2}" for handling the same "{3}" callback. \
"AllowsMultipleMethodsOnSameCallback" property of MetaDataDefaults can be \
set to true to supress this exception.
missing-no-arg-constructor: Entity listener class "{0}" must declare a no-arg \
constructor. "AllowsNoArgConstructorCallback" property of MetaDataDefaults \
can be set to true to ignore this exception.
extended-provider: WARNING: Configured to use extended Persistence Provider \
"{0}".
unloadable-provider: WARNING: Can not load configured Persistence Provider \
"{0}" due to "{1}"
unrecognized-provider: WARNING: Configured to use non-recognized Persistence \
Provider "{0}"
extended-provider: NOTE: Found extended persistence provider "{0}".
unloadable-provider: WARNING: Unable to load persistence provider "{0}" due \
to "{1}"
unrecognized-provider: WARNING: Found unrecognized persistence provider "{0}" \
in place of OpenJPA provider. This provider's properties will not be used.
EntityManagerFactory-name: EntityManagerFactory implementation
EntityManagerFactory-desc: Allows extension of standard \
org.apache.openjpa.persistence.EntityManagerFactoryImpl for custom behavior.

View File

@ -105,11 +105,11 @@ datastore records.
<emphasis role="bold"><link linkend="jpa_overview_trans"><classname>
EntityTransaction</classname></link></emphasis>: Each <classname>EntityManager
</classname> has a one-to-one relation with a single <classname>
javax.persistence.EntityTransaction</classname>. <classname>EntityTransaction
</classname>s allow operations on persistent data to be grouped into units of
work that either completely succeed or completely fail, leaving the datastore in
its original state. These all-or-nothing operations are important for
maintaining data integrity.
javax.persistence.EntityTransaction</classname>. <classname>
EntityTransaction</classname>s allow operations on persistent data to be
grouped into units of work that either completely succeed or completely fail,
leaving the datastore in its original state. These all-or-nothing operations
are important for maintaining data integrity.
</para>
</listitem>
<listitem>
@ -178,38 +178,37 @@ container.
<programlisting>
// get an EntityManagerFactory using the Persistence class; typically
// the factory is cached for easy repeated use
EntityManagerFactory factory = Persistence.createEntityManagerFactory (null);
EntityManagerFactory factory = Persistence.createEntityManagerFactory(null);
// get an EntityManager from the factory
EntityManager em = factory.createEntityManager (PersistenceContextType.EXTENDED);
EntityManager em = factory.createEntityManager(PersistenceContextType.EXTENDED);
// updates take place within transactions
EntityTransaction tx = em.getTransaction ();
tx.begin ();
EntityTransaction tx = em.getTransaction();
tx.begin();
// query for all employees who work in our research division
// and put in over 40 hours a week average
Query query = em.createQuery ("select e from Employee e where "
Query query = em.createQuery("select e from Employee e where "
+ "e.division.name = 'Research' AND e.avgHours &gt; 40");
List results = query.getResultList ();
// give all those hard-working employees a raise
for (Object res : results)
{
for (Object res : results) {
Employee emp = (Employee) res;
emp.setSalary (emp.getSalary () * 1.1);
emp.setSalary(emp.getSalary() * 1.1);
}
// commit the updates and free resources
tx.commit ();
em.close ();
factory.close ();
tx.commit();
em.close();
factory.close();
</programlisting>
</example>
<para>
Within a container, the <classname>EntityManager</classname> will be injected
and transactional handled declaratively. Thus, the in-container version of the
example consists entirely of business logic:
and transactions will be handled declaratively. Thus, the in-container version
of the example consists entirely of business logic:
</para>
<example id="jpa_overview_arch_interact_inside">
<title>
@ -219,15 +218,14 @@ example consists entirely of business logic:
// query for all employees who work in our research division
// and put in over 40 hours a week average - note that the EntityManager em
// is injected using a @Resource annotation
Query query = em.createQuery ("select e from Employee e where "
Query query = em.createQuery("select e from Employee e where "
+ "e.division.name = 'Research' and e.avgHours &gt; 40");
List results = query.getResultList ();
List results = query.getResultList();
// give all those hard-working employees a raise
for (Object res : results)
{
for (Object res : results) {
emp = (Employee) res;
emp.setSalary (emp.getSalary () * 1.1);
emp.setSalary(emp.getSalary() * 1.1);
}
</programlisting>
</example>
@ -274,8 +272,8 @@ application.
<para>
The diagram above depicts the JPA exception architecture. All
exceptions are unchecked. JPA uses standard exceptions where
appropriate, most notably <classname> IllegalArgumentException</classname>s and
<classname> IllegalStateException</classname> s. The specification also provides
appropriate, most notably <classname>IllegalArgumentException</classname>s and
<classname>IllegalStateException</classname>s. The specification also provides
a few JPA-specific exceptions in the <literal>javax.persistence</literal>
package. These exceptions should be self-explanatory. See the
<ulink url="http://java.sun.com/javaee/5/docs/api">Javadoc</ulink> for

View File

@ -3,10 +3,14 @@
Conclusion
</title>
<para>
This concludes our overview of the JPA specification. The
<link linkend="jpa_tutorials_intro">OpenJPA Tutorials</link> continue your
This concludes our overview of the JPA specification.
<!--
### TUTORIAL
The <link linkend="jpa_tutorials_intro">OpenJPA Tutorials</link> continue your
JPA education with step-by-step instructions for building simple JPA
applications. The <link linkend="ref_guide_intro">OpenJPA Reference Guide</link>
applications.
-->
The <link linkend="ref_guide_intro">OpenJPA Reference Guide</link>
contains detailed documentation on all aspects of the OpenJPA implementation
and core development tools.
</para>

View File

@ -18,14 +18,15 @@
The diagram above presents an overview of the <classname>EntityManager
</classname> interface. For a complete treatment of the <classname>
EntityManager</classname> API, see the
<ulink url="jdo-javadoc/javax/jdo/EntityManager.html"> Javadoc</ulink>
documentation. Methods whose parameter signatures consist of an ellipsis (...)
are overloaded to take multiple parameter types.
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html">
Javadoc</ulink> documentation. Methods whose parameter signatures consist of
an ellipsis (...) are overloaded to take multiple parameter types.
</para>
<note>
<para>
OpenJPA extends the standard <classname>EntityManager</classname> interface with
the <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
the
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>org.apache.openjpa.persistence.OpenJPAEntityManager</classname>
</ulink> interface to provide additional functionality.
</para>
@ -100,7 +101,7 @@ Every <classname>EntityManager</classname> has a one-to-one relation with an
</link> instance. In fact, many vendors use a single class to implement both the
<classname>EntityManager</classname> and <classname>EntityTransaction
</classname> interfaces. If your application requires multiple concurrent
transactions, you will use multiple <classname>EntityManager</classname> s.
transactions, you will use multiple <classname>EntityManager</classname>s.
</para>
<para>
You can retrieve the <classname>EntityTransaction</classname> associated with an
@ -129,7 +130,7 @@ demarcation or through the Java Transaction API (JTA) rather than through the
lifecycle state of entity instances.
</para>
<programlisting>
public void persist (Object entity);
public void persist(Object entity);
</programlisting>
<para>
<indexterm>
@ -198,7 +199,7 @@ whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
This action can only be used in the context of an active transaction.
</para>
<programlisting>
public void remove (Object entity);
public void remove(Object entity);
</programlisting>
<para>
<indexterm>
@ -268,7 +269,7 @@ whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
This action can only be used in the context of an active transaction.
</para>
<programlisting>
public void refresh (Object entity);
public void refresh(Object entity);
</programlisting>
<para>
<indexterm>
@ -345,7 +346,7 @@ whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
</listitem>
</itemizedlist>
<programlisting>
public Object merge (Object entity);
public Object merge(Object entity);
</programlisting>
<para>
<indexterm>
@ -562,27 +563,27 @@ well as all transaction demarcation code.
</indexterm>
<programlisting>
// create some objects
Magazine mag = new Magazine ("1B78-YU9L", "JavaWorld");
Magazine mag = new Magazine("1B78-YU9L", "JavaWorld");
Company pub = new Company ("Weston House");
pub.setRevenue (1750000D);
mag.setPublisher (pub);
pub.addMagazine (mag);
Company pub = new Company("Weston House");
pub.setRevenue(1750000D);
mag.setPublisher(pub);
pub.addMagazine(mag);
Article art = new Article ("JPA Rules!", "Transparent Object Persistence");
art.addAuthor (new Author ("Fred", "Hoyle"));
mag.addArticle (art);
Article art = new Article("JPA Rules!", "Transparent Object Persistence");
art.addAuthor(new Author("Fred", "Hoyle"));
mag.addArticle(art);
// persist
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
em.persist (mag);
em.persist (pub);
em.persist (art);
em.getTransaction ().commit ();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(mag);
em.persist(pub);
em.persist(art);
em.getTransaction().commit();
// or we could continue using the EntityManager...
em.close ();
em.close();
</programlisting>
</example>
<example id="jpa_overview_em_lifecycle_update">
@ -601,23 +602,23 @@ em.close ();
</tertiary>
</indexterm>
<programlisting>
Magazine.MagazineId mi = new Magazine.MagazineId ();
Magazine.MagazineId mi = new Magazine.MagazineId();
mi.isbn = "1B78-YU9L";
mi.title = "JavaWorld";
// updates should always be made within transactions; note that
// there is no code explicitly linking the magazine or company
// with the transaction; JPA automatically tracks all changes
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Magazine mag = em.find (Magazine.class, mi);
mag.setPrice (5.99);
Company pub = mag.getPublisher ();
pub.setRevenue (1750000D);
em.getTransaction ().commit ();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Magazine mag = em.find(Magazine.class, mi);
mag.setPrice(5.99);
Company pub = mag.getPublisher();
pub.setRevenue(1750000D);
em.getTransaction().commit();
// or we could continue using the EntityManager...
em.close ();
em.close();
</programlisting>
</example>
<example id="jpa_overview_em_lifecycle_delete">
@ -641,16 +642,16 @@ em.close ();
Object oid = ...;
// deletes should always be made within transactions
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Company pub = (Company) em.find (Company.class, oid);
for (Subscription sub : pub.getSubscriptions ())
em.remove (sub);
pub.getSubscriptions ().clear ();
em.getTransaction ().commit ();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Company pub = (Company) em.find(Company.class, oid);
for (Subscription sub : pub.getSubscriptions())
em.remove(sub);
pub.getSubscriptions().clear();
em.getTransaction().commit();
// or we could continue using the EntityManager...
em.close ();
em.close();
</programlisting>
</example>
<example id="jpa_overview_em_detachex">
@ -665,37 +666,37 @@ and transactions.
<programlisting>
// CLIENT:
// requests an object with a given oid
Record detached = (Record) getFromServer (oid);
Record detached = (Record) getFromServer(oid);
...
// SERVER:
// send object to client; object detaches on EM close
Object oid = processClientRequest ();
EntityManager em = emf.createEntityManager ();
Record record = em.find (Record.class, oid);
em.close ();
sendToClient (record);
Object oid = processClientRequest();
EntityManager em = emf.createEntityManager();
Record record = em.find(Record.class, oid);
em.close();
sendToClient(record);
...
// CLIENT:
// makes some modifications and sends back to server
detached.setSomeField ("bar");
sendToServer (detached);
detached.setSomeField("bar");
sendToServer(detached);
...
// SERVER:
// merges the instance and commit the changes
Record modified = (Record) processClientRequest ();
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Record merged = (Record) em.merge (modified);
merged.setLastModified (System.currentTimeMillis ());
merged.setModifier (getClientIdentityCode ());
em.getTransaction ().commit ();
em.close ();
Record modified = (Record) processClientRequest();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Record merged = (Record) em.merge(modified);
merged.setLastModified(System.currentTimeMillis());
merged.setModifier(getClientIdentityCode());
em.getTransaction().commit();
em.close();
</programlisting>
</example>
</section>
@ -713,7 +714,7 @@ context type of the <classname>EntityManager</classname>; see
persistence contexts.
</para>
<programlisting>
public &lt;T&gt; T find (Class&lt;T&gt; cls, Object oid);
public &lt;T&gt; T find(Class&lt;T&gt; cls, Object oid);
</programlisting>
<para>
<indexterm>
@ -751,7 +752,7 @@ entity with the given type and identity exists in the datastore, this method
returns null.
</para>
<programlisting>
public &lt;T&gt; T getReference (Class&lt;T&gt; cls, Object oid);
public &lt;T&gt; T getReference(Class&lt;T&gt; cls, Object oid);
</programlisting>
<para>
<indexterm>
@ -794,11 +795,11 @@ gets loaded when you attempt to access a persistent field. At that time, the
implementation may throw an <classname>EntityNotFoundException</classname> if it
discovers that the entity does not exist in the datastore. The implementation
may also throw an <classname>EntityNotFoundException</classname> from the
<methodname>getReference</methodname> method itself. Unlike <methodname>find
</methodname>, <methodname>getReference</methodname> does not return null.
<methodname>getReference</methodname> method itself. Unlike <methodname>
find</methodname>, <methodname>getReference</methodname> does not return null.
</para>
<programlisting>
public boolean contains (Object entity);
public boolean contains(Object entity);
</programlisting>
<para>
<indexterm>
@ -835,7 +836,7 @@ persistence context.
</secondary>
</indexterm>
<programlisting>
public void flush ();
public void flush();
</programlisting>
<para>
<indexterm>
@ -875,8 +876,8 @@ progress, the <methodname>flush</methodname> method throws a <classname>
TransactionRequiredException</classname>.
</para>
<programlisting>
public FlushModeType getFlushMode ();
public void setFlushMode (FlushModeType flushMode);
public FlushModeType getFlushMode();
public void setFlushMode(FlushModeType flushMode);
</programlisting>
<para>
<indexterm>
@ -928,7 +929,7 @@ control over flushing behavior. See the Reference Guide's
</para>
</note>
<programlisting>
public void clear ();
public void clear();
</programlisting>
<para>
<indexterm>
@ -976,7 +977,7 @@ persistence context. All entities managed by the <classname>EntityManager
</secondary>
</indexterm>
<programlisting>
public Query createQuery (String query);
public Query createQuery(String query);
</programlisting>
<para>
<classname>Query</classname> objects are used to find entities matching certain
@ -985,7 +986,7 @@ the given Java Persistence Query Language (JPQL) string. See
<xref linkend="jpa_overview_query"/> for details.
</para>
<programlisting>
public Query createNamedQuery (String name);
public Query createNamedQuery(String name);
</programlisting>
<para>
This method retrieves a query defined in metadata by name. The returned
@ -994,9 +995,9 @@ declared in metadata. For more information on named queries, read
<xref linkend="jpa_overview_query_named"/>.
</para>
<programlisting>
public Query createNativeQuery (String sql);
public Query createNativeQuery (String sql, Class resultCls);
public Query createNativeQuery (String sql, String resultMapping);
public Query createNativeQuery(String sql);
public Query createNativeQuery(String sql, Class resultCls);
public Query createNativeQuery(String sql, String resultMapping);
</programlisting>
<para>
<emphasis>Native</emphasis> queries are queries in the datastore's native
@ -1018,8 +1019,8 @@ native query support.
</secondary>
</indexterm>
<programlisting>
public boolean isOpen ();
public void close ();
public boolean isOpen();
public void close();
</programlisting>
<para>
When an <classname>EntityManager</classname> is no longer needed, you should

View File

@ -22,7 +22,7 @@ EntityManager</classname> instances for application use.
<para>
OpenJPA extends the standard <classname>EntityManagerFactory</classname>
interface with the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<classname>OpenJPAEntityManagerFactory</classname></ulink> to provide additional
functionality.
</para>
@ -73,9 +73,9 @@ vendors to pool factories, cutting down on resource utilization.
JNDI
</primary>
</indexterm>
JPA allows you to create and configure an <classname>EntityManagerFactory
</classname>, then store it in a Java Naming and Directory Interface (JNDI)
tree for later retrieval and use.
JPA allows you to create and configure an <classname>
EntityManagerFactory</classname>, then store it in a Java Naming and Directory
Interface (JNDI) tree for later retrieval and use.
</para>
</section>
<section id="jpa_overview_emfactory_em">
@ -102,8 +102,8 @@ tree for later retrieval and use.
</secondary>
</indexterm>
<programlisting>
public EntityManager createEntityManager ();
public EntityManager createEntityManager (Map map);
public EntityManager createEntityManager();
public EntityManager createEntityManager(Map map);
</programlisting>
<para>
The two <methodname>createEntityManager</methodname> methods above create a new
@ -144,8 +144,8 @@ createEntityManager</methodname>:
<literal>openjpa.&lt;property&gt;</literal>, where <emphasis>&lt;property&gt;
</emphasis> is any JavaBean property of the
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname> org.apache.openjpa.persistence.OpenJPAEntityManager</classname>
</ulink>.
<classname>
org.apache.openjpa.persistence.OpenJPAEntityManager</classname></ulink>.
</para>
</listitem>
</itemizedlist>
@ -217,7 +217,7 @@ merging detached entities.
<para>
Injected <classname>EntityManager</classname>s have use a <emphasis>transaction
</emphasis>, while <classname> EntityManager</classname>s obtained through the
<classname>EntityManagerFactory</classname> have an <emphasis> extended
<classname>EntityManagerFactory</classname> have an <emphasis>extended
</emphasis> persistence context. We describe these persistence context types
below.
</para>
@ -276,9 +276,9 @@ EntityManager em; // injected
// each operation occurs in a separate persistence context, and returns
// a new detached instance
Magazine mag1 = em.find (Magazine.class, magId);
Magazine mag2 = em.find (Magazine.class, magId);
assertTrue (mag2 != mag1);
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 != mag1);
...
// transaction begins:
@ -287,17 +287,17 @@ assertTrue (mag2 != mag1);
// detached objects. however, two lookups within the same transaction
// return the same instance, because the persistence context spans the
// transaction
Magazine mag3 = em.find (Magazine.class, magId);
assertTrue (mag3 != mag1 &amp;&amp; mag3 != mag2);
Magazine mag4 = em.find (Magazine.class (magId);
assertTrue (mag4 == mag3);
Magazine mag3 = em.find(Magazine.class, magId);
assertTrue(mag3 != mag1 &amp;&amp; mag3 != mag2);
Magazine mag4 = em.find(Magazine.class (magId);
assertTrue(mag4 == mag3);
...
// transaction commits:
// once again, each operation returns a new instance
Magazine mag5 = em.find (Magazine.class, magId);
assertTrue (mag5 != mag3);
Magazine mag5 = em.find(Magazine.class, magId);
assertTrue(mag5 != mag3);
</programlisting>
</example>
</section>
@ -324,30 +324,30 @@ EntityManager</classname> using an extended persistence context.
</para>
<programlisting>
EntityManagerFactory emf = ...
EntityManager em = emf.createEntityManager (PersistenceContextType.EXTENDED);
EntityManager em = emf.createEntityManager();
// persistence context active for entire life of EM, so only one entity
// for a given persistent identity
Magazine mag1 = em.find (Magazine.class, magId);
Magazine mag2 = em.find (Magazine.class, magId);
assertTrue (mag2 == mag1);
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 == mag1);
em.getTransaction ().begin ();
em.getTransaction().begin();
// same persistence context active within the transaction
Magazine mag3 = em.find (Magazine.class, magId);
assertTrue (mag3 == mag1);
Magazine mag4 = em.find (Magazine.class (magId);
assertTrue (mag4 == mag1);
Magazine mag3 = em.find(Magazine.class, magId);
assertTrue(mag3 == mag1);
Magazine mag4 = em.find(Magazine.class (magId);
assertTrue(mag4 == mag1);
em.getTransaction.commit ();
// when the transaction commits, instance still managed
Magazine mag5 = em.find (Magazine.class, magId);
assertTrue (mag5 == mag1);
Magazine mag5 = em.find(Magazine.class, magId);
assertTrue(mag5 == mag1);
// instance finally becomes detached when EM closes
em.close ();
em.close();
</programlisting>
</example>
</section>
@ -389,8 +389,8 @@ close the factory, or only close it when the application is exiting. Only
applications that require multiple factories with different configurations have
an obvious reason to create and close multiple <classname>EntityManagerFactory
</classname> instances. Once a factory is closed, all methods except
<methodname>isOpen</methodname> throw an <classname> IllegalStateException
</classname>.
<methodname>isOpen</methodname> throw an <classname>
IllegalStateException</classname>.
</para>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -56,9 +56,9 @@ strategies:
<orderedlist>
<listitem>
<para>
In a resource named <filename>orm.xml</filename> placed in the <filename>
META-INF</filename> directory of the classpath or the jar archive containing
your persistent classes.
In a resource named <filename>orm.xml</filename> placed in a <filename>
META-INF</filename> directory within a directory in your classpath or within a
jar archive containing your persistent classes.
</para>
</listitem>
<listitem>
@ -221,7 +221,7 @@ attribute:
<itemizedlist>
<listitem>
<para>
<literal>class</literal>: This required attribute lists the class name for the
<literal>class</literal>: Set this required attribute to the name of the
identity class.
</para>
</listitem>
@ -413,19 +413,16 @@ package org.mag;
@Entity
@IdClass(Magazine.MagazineId.class)
public class Magazine
{
public class Magazine {
...
public static class MagazineId
{
public static class MagazineId {
...
}
}
@Entity
public class Article
{
public class Article {
...
}
@ -433,20 +430,17 @@ public class Article
package org.mag.pub;
@Entity
public class Company
{
public class Company {
...
}
@Entity
public class Author
{
public class Author {
...
}
@Embeddable
public class Address
{
public class Address {
...
}
@ -454,42 +448,36 @@ public class Address
package org.mag.subscribe;
@MappedSuperclass
public abstract class Document
{
public abstract class Document {
...
}
@Entity
public class Contract
extends Document
{
extends Document {
...
}
@Entity
public class Subscription
{
public class Subscription {
...
@Entity
public static class LineItem
extends Contract
{
extends Contract {
...
}
}
@Entity(name="Lifetime")
public class LifetimeSubscription
extends Subscription
{
extends Subscription {
...
}
@Entity(name="Trial")
public class TrialSubscription
extends Subscription
{
extends Subscription {
...
}
</programlisting>
@ -587,19 +575,19 @@ Property access, on the other hand, retrieves and loads state through JavaBean
<literal>T</literal>, you must define the following getter method:
</para>
<programlisting>
T getP ();
T getP();
</programlisting>
<para>
For boolean properties, this is also acceptable:
</para>
<programlisting>
boolean isP ();
boolean isP();
</programlisting>
<para>
You must also define the following setter method:
</para>
<programlisting>
void setP (T value);
void setP(T value);
</programlisting>
<para>
To use property access, set your <literal>entity</literal> element's <literal>
@ -608,9 +596,9 @@ metadata and mapping annotations on the getter method:
</para>
<programlisting>
@ManyToOne
private Company getPublisher () { ... }
private Company getPublisher() { ... }
private void setPublisher (Company publisher) { ... }
private void setPublisher(Company publisher) { ... }
</programlisting>
<warning>
<para>
@ -662,7 +650,7 @@ either a persistent field or a persistent property.
<para>
The <classname>Transient</classname> annotation specifies that a field is
non-persistent. Use it to exclude fields from management that would otherwise be
persistent. <classname> Transient</classname> is a marker annotation only; it
persistent. <classname>Transient</classname> is a marker annotation only; it
has no properties.
</para>
<para>
@ -873,8 +861,8 @@ represents the UUID as a 32-character hexadecimal string.
</itemizedlist>
<para>
These string constants are defined in
<ulink url="../../api/openjpa/persistence/Generator.html"><classname>
org.apache.openjpa.persistence.Generator</classname></ulink>.
<ulink url="../apidocs/org/apache/openjpa/persistence/Generator.html">
<classname>org.apache.openjpa.persistence.Generator</classname></ulink>.
</para>
</note>
</section>
@ -998,13 +986,13 @@ attribute is required.
<classname>Basic</classname> signifies a standard value persisted as-is to the
datastore. You can use the <classname>Basic</classname> annotation on persistent
fields of the following types: primitives, primitive wrappers, <classname>
java.lang.String</classname>, <classname>byte[]</classname>, <classname>Byte[]
</classname>, <classname>char[]</classname>, <classname>Character[]</classname>
, <classname>java.math.BigDecimal</classname>, <classname>java.math.BigInteger
</classname>, <classname>java.util.Date</classname>, <classname>
java.util.Calendar</classname>, <classname>java.sql.Date</classname>,
<classname>java.sql.Timestamp</classname>, <classname>Enum</classname> s, and
<classname>Serializable</classname> types.
java.lang.String</classname>, <classname>byte[]</classname>, <classname>
Byte[]</classname>, <classname>char[]</classname>, <classname>
Character[]</classname>, <classname>java.math.BigDecimal</classname>,
<classname>java.math.BigInteger</classname>, <classname>
java.util.Date</classname>, <classname>java.util.Calendar</classname>,
<classname>java.sql.Date</classname>, <classname>java.sql.Timestamp</classname>,
<classname>Enum</classname>s, and <classname>Serializable</classname> types.
</para>
<para>
<classname>Basic</classname> declares these properties:
@ -1012,9 +1000,9 @@ java.util.Calendar</classname>, <classname>java.sql.Date</classname>,
<itemizedlist>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly (
<literal>FetchType.EAGER</literal>) or lazily ( <literal>FetchType.LAZY
</literal> ). Defaults to <literal>FetchType.EAGER</literal>.
<literal>FetchType fetch</literal>: Whether to load the field eagerly
(<literal>FetchType.EAGER</literal>) or lazily (<literal>
FetchType.LAZY</literal>). Defaults to <literal>FetchType.EAGER</literal>.
</para>
</listitem>
<listitem>
@ -1187,8 +1175,8 @@ required.
</secondary>
</indexterm>
<para>
When an entity <literal>A</literal> references a single entity <literal>B
</literal>, and other <literal>A</literal>s might also reference the same
When an entity <literal>A</literal> references a single entity <literal>
B</literal>, and other <literal>A</literal>s might also reference the same
<literal>B</literal>, we say there is a <emphasis>many to one</emphasis>
relation from <literal>A</literal> to <literal>B</literal>. In our sample
model, for example, each magazine has a reference to its publisher. Multiple
@ -1214,18 +1202,18 @@ behavior for this field. We explore cascades below. Defaults to an empty array.
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly (
<literal>FetchType.EAGER</literal>) or lazily ( <literal>FetchType.LAZY
</literal> ). Defaults to <literal>FetchType.EAGER</literal>. See
<xref linkend="jpa_overview_meta_fetch"/> above for details on fetch
types.
<literal>FetchType fetch</literal>: Whether to load the field eagerly
(<literal>FetchType.EAGER</literal>) or lazily
(<literal>FetchType.LAZY</literal>). Defaults to <literal>
FetchType.EAGER</literal>. See <xref linkend="jpa_overview_meta_fetch"/> above
for details on fetch types.
</para>
</listitem>
<listitem>
<para>
<literal>boolean optional</literal>: Whether the related object must exist. If
<literal>false</literal>, this field cannot be null. Defaults to <literal>true
</literal>.
<literal>false</literal>, this field cannot be null. Defaults to <literal>
true</literal>.
</para>
</listitem>
</itemizedlist>
@ -1247,8 +1235,8 @@ required.
</listitem>
<listitem>
<para>
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>LAZY
</literal>.
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>
LAZY</literal>.
</para>
</listitem>
<listitem>
@ -1279,7 +1267,7 @@ null.
We introduce the JPA <classname>EntityManager</classname> in
<xref linkend="jpa_overview_em"/>. The <classname>EntityManager
</classname> has APIs to persist new entities, remove (delete) existing
entities, refresh entity state from the datastore, and merge <emphasis> detached
entities, refresh entity state from the datastore, and merge <emphasis>detached
</emphasis> entity state back into the persistence context. We explore all of
these APIs in detail later in the overview.
</para>
@ -1386,8 +1374,8 @@ equivalent:
</indexterm>
<para>
When an entity <literal>A</literal> references multiple <literal>B</literal>
entities, and no two <literal>A</literal>s reference the same <literal>B
</literal>, we say there is a <emphasis>one to many</emphasis> relation from
entities, and no two <literal>A</literal>s reference the same <literal>
B</literal>, we say there is a <emphasis>one to many</emphasis> relation from
<literal>A</literal> to <literal>B</literal>.
</para>
<para>
@ -1428,11 +1416,11 @@ behavior for the collection elements. We explore cascades above in
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly (
<literal>FetchType.EAGER</literal>) or lazily ( <literal>FetchType.LAZY
</literal> ). Defaults to <literal>FetchType.LAZY</literal>. See
<xref linkend="jpa_overview_meta_fetch"/> above for details on fetch
types.
<literal>FetchType fetch</literal>: Whether to load the field eagerly
(<literal>FetchType.EAGER</literal>) or lazily
(<literal>FetchType.LAZY</literal>). Defaults to <literal>
FetchType.LAZY</literal>. See <xref linkend="jpa_overview_meta_fetch"/> above
for details on fetch types.
</para>
</listitem>
</itemizedlist>
@ -1454,8 +1442,8 @@ required.
</listitem>
<listitem>
<para>
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>LAZY
</literal>.
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>
LAZY</literal>.
</para>
</listitem>
<listitem>
@ -1578,8 +1566,8 @@ Reference Guide for details.
</secondary>
</indexterm>
<para>
When an entity <literal>A</literal> references a single entity <literal>B
</literal>, and no other <literal>A</literal>s can reference the same <literal>
When an entity <literal>A</literal> references a single entity <literal>
B</literal>, and no other <literal>A</literal>s can reference the same <literal>
B</literal>, we say there is a <emphasis>one to one</emphasis> relation between
<literal>A</literal> and <literal>B</literal>. In our sample model, <classname>
Magazine</classname> has a one to one relation to <classname>Article</classname>
@ -1615,18 +1603,18 @@ array.
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly (
<literal>FetchType.EAGER</literal>) or lazily ( <literal>FetchType.LAZY
</literal> ). Defaults to <literal>FetchType.EAGER</literal>. See
<xref linkend="jpa_overview_meta_fetch"/> above for details on fetch
types.
<literal>FetchType fetch</literal>: Whether to load the field eagerly
(<literal>FetchType.EAGER</literal>) or lazily
(<literal>FetchType.LAZY</literal>). Defaults to <literal>
FetchType.EAGER</literal>. See <xref linkend="jpa_overview_meta_fetch"/> above
for details on fetch types.
</para>
</listitem>
<listitem>
<para>
<literal>boolean optional</literal>: Whether the related object must exist. If
<literal>false</literal>, this field cannot be null. Defaults to <literal>true
</literal>.
<literal>false</literal>, this field cannot be null. Defaults to <literal>
true</literal>.
</para>
</listitem>
</itemizedlist>
@ -1648,8 +1636,8 @@ required.
</listitem>
<listitem>
<para>
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>LAZY
</literal>.
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>
LAZY</literal>.
</para>
</listitem>
<listitem>
@ -1692,7 +1680,7 @@ one-to-one</literal> element.
<para>
When an entity <literal>A</literal> references multiple <literal>B</literal>
entities, and other <literal>A</literal>s might reference some of the same
<literal>B</literal> s, we say there is a <emphasis>many to many</emphasis>
<literal>B</literal>s, we say there is a <emphasis>many to many</emphasis>
relation between <literal>A</literal> and <literal>B</literal>. In our sample
model, for example, each article has a reference to all the authors that
contributed to the article. Other articles might have some of the same authors.
@ -1730,11 +1718,11 @@ behavior for the collection elements. We explore cascades above in
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly (
<literal>FetchType.EAGER</literal>) or lazily ( <literal>FetchType.LAZY
</literal> ). Defaults to <literal>FetchType.LAZY</literal>. See
<xref linkend="jpa_overview_meta_fetch"/> above for details on fetch
types.
<literal>FetchType fetch</literal>: Whether to load the field eagerly
(<literal>FetchType.EAGER</literal>) or lazily
(<literal>FetchType.LAZY</literal>). Defaults to <literal>
FetchType.LAZY</literal>. See <xref linkend="jpa_overview_meta_fetch"/> above
for details on fetch types.
</para>
</listitem>
</itemizedlist>
@ -1756,8 +1744,8 @@ required.
</listitem>
<listitem>
<para>
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>LAZY
</literal>.
<literal>fetch</literal>: One of <literal>EAGER</literal> or <literal>
LAZY</literal>.
</para>
</listitem>
<listitem>
@ -1905,21 +1893,21 @@ Fields declared <literal>static, transient</literal>, or <literal>final
<listitem>
<para>
Fields of any primitive type, primitive wrapper type, <classname>
java.lang.String</classname>, <classname>byte[]</classname>, <classname>Byte[]
</classname>, <classname>char[]</classname>, <classname>Character[]</classname>
, <classname>java.math.BigDecimal</classname>, <classname>java.math.BigInteger
</classname>, <classname>java.util.Date</classname>, <classname>
java.util.Calendar</classname>, <classname>java.sql.Date</classname>,
<classname>java.sql.Timestamp</classname>, or any <classname>Serializable
</classname> type default to persistent, as if annotated with
<link linkend="jpa_overview_meta_basic"><literal>@Basic</literal></link>.
java.lang.String</classname>, <classname>byte[]</classname>, <classname>
Byte[]</classname>, <classname>char[]</classname>, <classname>
Character[]</classname>, <classname>java.math.BigDecimal</classname>,
<classname>java.math.BigInteger</classname>, <classname>
java.util.Date</classname>, <classname> java.util.Calendar</classname>,
<classname>java.sql.Date</classname>, <classname>java.sql.Timestamp</classname>,
or any <classname>Serializable</classname> type default to persistent, as if
annotated with <link linkend="jpa_overview_meta_basic"><literal>
@Basic</literal></link>.
</para>
</listitem>
<listitem>
<para>
Fields of an embeddable type default to persistent, as if annotated with
<link linkend="jpa_overview_meta_embedded"><literal> @Embedded</literal></link>
.
<link linkend="jpa_overview_meta_embedded"><literal>@Embedded</literal></link>.
</para>
</listitem>
<listitem>
@ -3500,8 +3488,8 @@ package org.mag;
@Entity
@IdClass(Magazine.MagazineId.class)
public class Magazine
{
public class Magazine {
@Id private String isbn;
@Id private String title;
@Version private int version;
@ -3524,15 +3512,14 @@ public class Magazine
...
public static class MagazineId
{
public static class MagazineId {
...
}
}
@Entity
public class Article
{
public class Article {
@Id private long id;
@Version private int version;
@ -3550,8 +3537,8 @@ public class Article
package org.mag.pub;
@Entity
public class Company
{
public class Company {
@Id private long id;
@Version private int version;
@ -3569,8 +3556,8 @@ public class Company
}
@Entity
public class Author
{
public class Author {
@Id private long id;
@Version private int version;
@ -3585,8 +3572,8 @@ public class Author
}
@Embeddable
public class Address
{
public class Address {
private String street; // defaults to @Basic
private String city; // defaults to @Basic
private String state; // defaults to @Basic
@ -3599,8 +3586,8 @@ public class Address
package org.mag.subscribe;
@MappedSuperclass
public abstract class Document
{
public abstract class Document {
@Id private long id;
@Version private int version;
@ -3609,16 +3596,16 @@ public abstract class Document
@Entity
public class Contract
extends Document
{
extends Document {
private String terms; // defaults to @Basic
...
}
@Entity
public class Subscription
{
public class Subscription {
@Id private long id;
@Version private int version;
@ -3633,8 +3620,8 @@ public class Subscription
@Entity
public static class LineItem
extends Contract
{
extends Contract {
private String comments; // defaults to @Basic
private double price; // defaults to @Basic
private long num; // defaults to @Basic
@ -3648,21 +3635,21 @@ public class Subscription
@Entity(name="Lifetime")
public class LifetimeSubscription
extends Subscription
{
extends Subscription {
@Basic(fetch=FetchType.LAZY)
private boolean getEliteClub () { ... }
public void setEliteClub (boolean elite) { ... }
private boolean getEliteClub() { ... }
public void setEliteClub(boolean elite) { ... }
...
}
@Entity(name="Trial")
public class TrialSubscription
extends Subscription
{
public Date getEndDate () { ... }
public void setEndDate (Date end) { ... }
extends Subscription {
public Date getEndDate() { ... }
public void setEndDate(Date end) { ... }
...
}

View File

@ -35,7 +35,7 @@
</see>
</indexterm>
<para>
JPA recognizes two types of persistent classes: <emphasis> entity</emphasis>
JPA recognizes two types of persistent classes: <emphasis>entity</emphasis>
classes and <emphasis>embeddable</emphasis> classes. Each persistent instance of
an entity class - each <emphasis>entity</emphasis> - represents a unique
datastore record. You can use the <classname>EntityManager</classname> to find
@ -49,9 +49,9 @@ never returned directly from the <classname>EntityManager</classname> or from a
<classname>Query</classname>.
</para>
<para>
Despite these differences, there are few differences between entity classes and
embeddable classes. In fact, writing either type of persistent class is little
different than writing any other class. There are no special parent classes to
Despite these differences, there are few distinctions between entity classes and
embeddable classes. In fact, writing either type of persistent class is a lot
like writing any other class. There are no special parent classes to
extend from, field types to use, or methods to write. This is one important way
in which JPA makes persistence transparent to you, the developer.
</para>
@ -73,43 +73,38 @@ package org.mag;
* Example persistent class. Notice that it looks exactly like any other
* class. JPA makes writing persistent classes completely transparent.
*/
public class Magazine
{
private String isbn;
private String title;
private Set articles = new HashSet ();
private Article coverArticle;
private int copiesSold;
private double price;
private Company publisher;
private int version;
public class Magazine {
protected Magazine ()
{
private String isbn;
private String title;
private Set articles = new HashSet();
private Article coverArticle;
private int copiesSold;
private double price;
private Company publisher;
private int version;
protected Magazine() {
}
public Magazine (String title, String isbn)
{
public Magazine(String title, String isbn) {
this.title = title;
this.isbn = isbn;
}
public void publish (Company publisher, double price)
{
public void publish(Company publisher, double price) {
this.publisher = publisher;
publisher.addMagazine (this);
publisher.addMagazine(this);
this.price = price;
}
public void sell ()
{
public void sell() {
copiesSold++;
publisher.addRevenue (price);
publisher.addRevenue(price);
}
public void addArticle (Article article)
{
articles.add (article);
public void addArticle(Article article) {
articles.add(article);
}
// rest of methods omitted
@ -210,7 +205,7 @@ are identity fields, because no two magazine records in the datastore can have
the same <literal>isbn</literal> and <literal>title</literal> values.
<xref linkend="jpa_overview_meta_id"/> will show you how to denote your
identity fields in JPA metadata. <xref linkend="jpa_overview_pc_identity"/>
below examines persistent identity.
below examines persistent identity.
</para>
<note>
<para>
@ -241,24 +236,24 @@ OpenJPA fully supports identity fields, but does not require them. See
</indexterm>
<para>
The <literal>version</literal> field in our <classname>Magazine</classname>
class may seem out of place. JPA uses a version field in your entity to detect
class may seem out of place. JPA uses a version field in your entities to detect
concurrent modifications to the same datastore record. When the JPA runtime
detects an attempt to concurrently modify the same record, it throws an
exception to the transaction attempting to commit last. This prevents
overwriting the previous commit with stale data.
</para>
<para>
The version field is not required, but without one concurrent threads or
A version field is not required, but without one concurrent threads or
processes might succeed in making conflicting changes to the same record at the
same time. This is unacceptable to most applications.
<xref linkend="jpa_overview_meta_version"/> shows you how to designate a
version field in JPA metadata.
</para>
<para>
The version field must be an integral type ( <classname> int</classname>,
<classname>Long</classname>, etc) or a <classname>java.sql.Timestamp</classname>
. You should consider version fields immutable. Changing the field value has
undefined results.
The version field must be an integral type (<classname> int</classname>,
<classname>Long</classname>, etc) or a <classname>
java.sql.Timestamp</classname>. You should consider version fields immutable.
Changing the field value has undefined results.
</para>
<note>
<para>
@ -391,12 +386,12 @@ the field. JPA supports the following immutable types:
<itemizedlist>
<listitem>
<para>
All primitives ( <classname>int, float, byte</classname>, etc)
All primitives (<classname>int, float, byte</classname>, etc)
</para>
</listitem>
<listitem>
<para>
All primitive wrappers ( <classname>java.lang.Integer, java.lang.Float,
All primitive wrappers (<classname>java.lang.Integer, java.lang.Float,
java.lang.Byte</classname>, etc)
</para>
</listitem>
@ -527,7 +522,7 @@ Embeddable types
<listitem>
<para>
<classname>java.util.Map</classname>s in which each entry maps the value of one
of an entity's fields to that entity.
of a related entity's fields to that entity.
</para>
</listitem>
</itemizedlist>
@ -560,10 +555,9 @@ information on persisting serializable types.
</para>
<note>
<para>
OpenJPA also supports arrays, <classname> java.lang.Number</classname>,
<classname> java.util.Locale</classname>, all JDK 1.2 <classname> Set
</classname>, <classname>List</classname>, and <classname> Map</classname>
types, collections and maps of immutable and embedded as well as entity types,
OpenJPA also supports arrays, <classname>java.lang.Number</classname>,
<classname>java.util.Locale</classname>, all JDK 1.2 <classname>Set</classname>,
<classname>List</classname>, and <classname>Map</classname> types,
and many other mutable and immutable field types. OpenJPA also allows you to
plug in support for custom types.
</para>
@ -688,10 +682,10 @@ in the datastore. Each entity's identity field values must be unique among all
other entites of the same type.
</para>
<para>
Identity fields must be primitives, primitive wrappers, <classname>String
</classname> s, <classname>Date</classname> s, <classname>Timestamp</classname>
s, or embeddable types. Notably, other entities instances can <emphasis>not
</emphasis> be used as identity fields.
Identity fields must be primitives, primitive wrappers, <classname>
String</classname>s, <classname>Date</classname>s, <classname>
Timestamp</classname>s, or embeddable types. Notably, other entities instances
can <emphasis>not</emphasis> be used as identity fields.
</para>
<note>
<para>
@ -726,7 +720,7 @@ as immutable objects in your applications.
</seealso>
</indexterm>
If you are dealing with a single persistence context (see
<xref linkend="jpa_overview_emfactory_perscontext"/> ), then you do not
<xref linkend="jpa_overview_emfactory_perscontext"/>), then you do not
have to compare identity fields to test whether two entity references represent
the same state in the datastore. There is a much easier way: the <literal>==
</literal> operator. JPA requires that each persistence context maintain only
@ -811,7 +805,7 @@ If the class is an inner class, it must be <literal>static</literal>.
All entity classes related by inheritance must use the same identity class, or
else each entity class must have its own identity class whose inheritance
hierarchy mirrors the inheritance hierarchy of the owning entity classes (see
<xref linkend="jpa_overview_pc_identity_hierarchy"/> ).
<xref linkend="jpa_overview_pc_identity_hierarchy"/>).
</para>
</listitem>
</itemizedlist>
@ -835,8 +829,8 @@ identity fields.
/**
* Persistent class using application identity.
*/
public class Magazine
{
public class Magazine {
private String isbn; // identity field
private String title; // identity field
@ -846,8 +840,8 @@ public class Magazine
/**
* Application identity class for Magazine.
*/
public static class MagazineId
{
public static class MagazineId {
// each identity field in the Magazine class must have a
// corresponding field in the identity class
public String isbn;
@ -859,8 +853,7 @@ public class Magazine
* classes directly (some JPA implementations may subclass the
* identity class).
*/
public boolean equals (Object other)
{
public boolean equals(Object other) {
if (other == this)
return true;
if (!(other instanceof MagazineId))
@ -868,22 +861,20 @@ public class Magazine
MagazineId mi = (MagazineId) other;
return (isbn == mi.isbn
|| (isbn != null &amp;&amp; isbn.equals (mi.isbn)))
|| (isbn != null &amp;&amp; isbn.equals(mi.isbn)))
&amp;&amp; (title == mi.title
|| (title != null &amp;&amp; title.equals (mi.title)));
|| (title != null &amp;&amp; title.equals(mi.title)));
}
/**
* Hashcode must also depend on identity values.
*/
public int hashCode ()
{
return ((isbn == null) ? 0 : isbn.hashCode ())
^ ((title == null) ? 0 : title.hashCode ());
public int hashCode() {
return ((isbn == null) ? 0 : isbn.hashCode())
^ ((title == null) ? 0 : title.hashCode());
}
public String toString ()
{
public String toString() {
return isbn + ":" + title;
}
}
@ -954,7 +945,7 @@ more identity fields.
<listitem>
<para>
All subclasses of a concrete identity class must be <methodname>equals
</methodname> and <methodname> hashCode</methodname> -compatible with the
</methodname> and <methodname>hashCode</methodname>-compatible with the
concrete superclass. This means that in our example, a <classname>ManagerId
</classname> instance and a <classname>FullTimeEmployeeId</classname> instance
with the same identity field values should have the same hash code, and should
@ -1106,8 +1097,8 @@ datastructure.
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PreUpdate.html">
<classname>PreUpdate</classname></ulink>: Methods marked with this annotation
will be invoked just the persistent values in your objects are flushed to the
datastore. This is equivalent to the XML element tag <literal>pre-update
</literal>.
datastore. This is equivalent to the XML element tag <literal>
pre-update</literal>.
</para>
<para>
<classname>PreUpdate</classname> is the complement to <classname>PostLoad
@ -1131,8 +1122,7 @@ persistent fields with information cached in non-persistent data.
<classname>PostUpdate</classname></ulink>: Methods marked with this annotation
will be invoked after changes to a given instance have been stored to the
datastore. This is useful for clearing stale data cached at the application
layer. This is equivalent to the XML element tag <literal>post-update</literal>
.
layer. This is equivalent to the XML element tag <literal>post-update</literal>.
</para>
</listitem>
<listitem>
@ -1150,8 +1140,8 @@ layer. This is equivalent to the XML element tag <literal>post-update</literal>
will be invoked before an object transactions to the deleted state. Access to
persistent fields is valid within this method. You might use this method to
cascade the deletion to related objects based on complex criteria, or to perform
other cleanup. This is equivalent to the XML element tag <literal>pre-remove
</literal>.
other cleanup. This is equivalent to the XML element tag <literal>
pre-remove</literal>.
</para>
</listitem>
<listitem>
@ -1189,8 +1179,8 @@ Below is an example of how to declare callback methods on persistent classes:
* Example persistent class declaring our entity listener.
*/
@Entity
public class Magazine
{
public class Magazine {
@Transient
private byte[][] data;
@ -1198,17 +1188,15 @@ public class Magazine
private List&lt;Photo&gt; photos;
@PostLoad
public void convertPhotos ()
{
data = new byte[photos.size ()][];
for (int i = 0; i &lt; photos.size (); i++)
data[i] = photos.get (i).toByteArray ();
public void convertPhotos() {
data = new byte[photos.size()][];
for (int i = 0; i &lt; photos.size(); i++)
data[i] = photos.get(i).toByteArray();
}
@PreDelete
public void logMagazineDeletion ()
{
getLog ().debug ("deleting magazine containing" + photos.size ()
public void logMagazineDeletion() {
getLog().debug("deleting magazine containing" + photos.size()
+ " photos.");
}
}
@ -1258,8 +1246,8 @@ classes.
*/
@Entity
@EntityListeners({ MagazineLogger.class, ... })
public class Magazine
{
public class Magazine {
// ... //
}
@ -1267,20 +1255,18 @@ public class Magazine
/**
* Example entity listener.
*/
public class MagazineLogger
{
public class MagazineLogger {
@PostPersist
public void logAddition (Object pc)
{
public void logAddition(Object pc) {
getLog ().debug ("Added new magazine:" + ((Magazine) pc).getTitle ());
}
@PreRemove
public void logDeletion (Object pc)
{
getLog ().debug ("Removing from circulation:" +
((Magazine) pc).getTitle ());
public void logDeletion(Object pc) {
getLog().debug("Removing from circulation:" +
((Magazine) pc).getTitle());
}
}
</programlisting>

View File

@ -35,15 +35,14 @@
<imageobject>
<!-- PNG image data, 427 x 121 (see README) -->
<imagedata fileref="img/persistence.png" width="285px"/>
</imageobject>
</mediaobject>
<note>
<para>
OpenJPA also includes the
<ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html"><classname>
OpenJPAPersistence</classname></ulink> helper class to provide additional
utility methods.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAPersistence.html">
<classname>OpenJPAPersistence</classname></ulink> helper class to provide
additional utility methods.
</para>
</note>
<para>
@ -55,8 +54,8 @@ of a container, however, can use the
EntityManagerFactory</classname> objects in a vendor-neutral fashion.
</para>
<programlisting>
public static EntityManagerFactory createEntityManagerFactory (String name);
public static EntityManagerFactory createEntityManagerFactory (String name, Map props);
public static EntityManagerFactory createEntityManagerFactory(String name);
public static EntityManagerFactory createEntityManagerFactory(String name, Map props);
</programlisting>
<para>
Each <methodname>createEntityManagerFactory</methodname> method searches the
@ -67,8 +66,8 @@ factory.
</para>
<para>
<filename>persistence.xml</filename> files define <classname>
EntityManagerFactories</classname>. The <methodname> createEntityManagerFactory
</methodname> methods search for <filename> persistence.xml</filename> files
EntityManagerFactories</classname>. The <methodname>createEntityManagerFactory
</methodname> methods search for <filename>persistence.xml</filename> files
within the <filename>META-INF</filename> directory of any <literal>CLASSPATH
</literal> element. For example, if your <literal>CLASSPATH</literal> contains
the <filename>conf</filename> directory, you could place an <classname>
@ -120,9 +119,9 @@ name attribute is required.
</listitem>
<listitem>
<para>
<literal>transaction-type</literal>: Whether to use managed ( <literal>JTA
</literal>) or local ( <literal>RESOURCE_LOCAL</literal>) transaction
management. Defaults to <literal>JTA</literal>.
<literal>transaction-type</literal>: Whether to use managed
(<literal>JTA</literal>) or local (<literal>RESOURCE_LOCAL</literal>)
transaction management.
</para>
</listitem>
<listitem>
@ -144,7 +143,7 @@ OpenJPA.
<para>
<literal>jta-data-source</literal>: The JNDI name of a JDBC <classname>
DataSource</classname> that is automatically enlisted in JTA transactions. This
may be an XA <classname> DataSource</classname>.
may be an XA <classname>DataSource</classname>.
</para>
</listitem>
<listitem>
@ -155,22 +154,22 @@ DataSource</classname> that is not enlisted in JTA transactions.
</listitem>
<listitem>
<para>
<literal>mapping-file</literal> *: The resource names of XML mapping files for
<literal>mapping-file</literal>*: The resource names of XML mapping files for
entities and embeddable classes. You can also specify mapping information in an
<filename> orm.xml</filename> file in your <filename>META-INF</filename>
<filename>orm.xml</filename> file in your <filename>META-INF</filename>
directory. If present, the <filename>orm.xml</filename> mapping file will be
read automatically.
</para>
</listitem>
<listitem>
<para>
<literal>jar-file</literal> *: The names of jar files containing entities and
<literal>jar-file</literal>*: The names of jar files containing entities and
embeddable classes. The implementation will scan the jar for annotated classes.
</para>
</listitem>
<listitem>
<para>
<literal>class</literal> *: The class names of entities and embeddable classes.
<literal>class</literal>*: The class names of entities and embeddable classes.
</para>
</listitem>
<listitem>
@ -234,11 +233,11 @@ EntityManagerFactories</classname> are typically injected.
<programlisting>
// if your persistence.xml file does not contain all settings already, you
// can add vendor settings to a map
Properties props = new Properties ();
Properties props = new Properties();
...
// create the factory defined by the "openjpa" entity-manager entry
EntityManagerFactory emf = Persistence.createEntityManagerFactory ("openjpa", props);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("openjpa", props);
</programlisting>
</example>
</section>

File diff suppressed because it is too large Load Diff

View File

@ -81,8 +81,8 @@ The <classname>EntityManager</classname> has two factory methods suitable for
creating SQL queries:
</para>
<programlisting>
public Query createNativeQuery (String sqlString, Class resultClass);
public Query createNativeQuery (String sqlString, String resultSetMapping);
public Query createNativeQuery(String sqlString, Class resultClass);
public Query createNativeQuery(String sqlString, String resultSetMapping);
</programlisting>
<para>
The first method is used to create a new <classname>Query</classname> instance
@ -99,8 +99,8 @@ action.
</title>
<programlisting>
EntityManager em = ...;
Query query = em.createNativeQuery ("SELECT * FROM MAG", Magazine.class);
processMagazines (query.getResultList ());
Query query = em.createNativeQuery("SELECT * FROM MAG", Magazine.class);
processMagazines(query.getResultList());
</programlisting>
</example>
<note>
@ -182,7 +182,6 @@ simple mapping between a class and the database:
<imageobject>
<!-- PNG image data, 320 x 149 (see README) -->
<imagedata fileref="img/sqlquery-model.png" width="213px"/>
</imageobject>
</mediaobject>
<example id="jpa_overview_sqlquery_objex">
@ -190,11 +189,11 @@ simple mapping between a class and the database:
Retrieving Persistent Objects
</title>
<programlisting>
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
Query query = em.createNativeQuery("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE &gt; 5 AND PRICE &lt; 10", Magazine.class);
List&lt;Magazine&gt; results = query.getResultList ();
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) query.getResultList();
for (Magazine mag : results)
processMagazine (mag);
processMagazine(mag);
</programlisting>
</example>
<para>
@ -207,13 +206,13 @@ magazines in any price range:
SQL Query Parameters
</title>
<programlisting>
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
Query query = em.createNativeQuery("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE &gt; ?1 AND PRICE &lt; ?2", Magazine.class);
query.setParameter (1, 5d);
query.setParameter (2, 10d);
query.setParameter(1, 5d);
query.setParameter(2, 10d);
List&lt;Magazine&gt; results = query.getResultList ();
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) query.getResultList();
for (Magazine mag : results)
processMagazine (mag);
</programlisting>

View File

@ -140,10 +140,9 @@ includes a method to transfer funds from one user to another, and it looks
something like this:
</para>
<programlisting>
public void transferFunds (User from, User to, double amnt)
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
public void transferFunds(User from, User to, double amnt) {
from.decrementAccount(amnt);
to.incrementAccount(amnt);
}
</programlisting>
<para>
@ -280,8 +279,8 @@ of hanging due to deadlock.
OpenJPA uses optimistic semantics by default, but supports both optimistic and
datastore transactions. OpenJPA also offers advanced locking and versioning APIs
for fine-grained control over database resource allocation and object
versioning. See <xref linkend="ref_guide_locking"/> of the Reference Guide for details
on locking. <xref linkend="jpa_overview_meta_version"/>
versioning. See <xref linkend="ref_guide_locking"/> of the Reference Guide for
details on locking. <xref linkend="jpa_overview_meta_version"/>
of this document covers standard object versioning, while
<xref linkend="ref_guide_mapping_jpa"/> of the Reference Guide discusses
additional versioning strategies available in OpenJPA.
@ -312,13 +311,13 @@ JPA integrates with your container's <emphasis>managed</emphasis> transactions,
allowing you to use the container's declarative transaction demarcation and its
Java Transaction API (JTA) implementation for transaction management. Outside of
a container, though, you must demarcate transactions manually through JPA. The
<classname> EntityTransaction</classname> interface controls unmanaged
<classname>EntityTransaction</classname> interface controls unmanaged
transactions in JPA.
</para>
<programlisting>
public void begin ();
public void commit ();
public void rollback ();
public void begin();
public void commit();
public void rollback();
</programlisting>
<para>
<indexterm>
@ -376,7 +375,7 @@ also ends the persistence context. All managed entites will be detached from the
<classname>EntityManager</classname>.
</para>
<programlisting>
public boolean isActive ();
public boolean isActive();
</programlisting>
<para>
<indexterm>
@ -388,31 +387,30 @@ public boolean isActive ();
</secondary>
</indexterm>
Finally, the <methodname>isActive</methodname> method returns <literal>true
</literal> if the transaction is in progress ( <methodname>begin</methodname>
</literal> if the transaction is in progress (<methodname>begin</methodname>
has been called more recently than <methodname>commit</methodname> or
<methodname>rollback</methodname> ), and <literal>false</literal> otherwise.
<methodname>rollback</methodname>), and <literal>false</literal> otherwise.
</para>
<example id="jpa_overview_trans_group">
<title>
Grouping Operations with Transactions
</title>
<programlisting>
public void transferFunds (EntityManager em, User from, User to, double amnt)
{
public void transferFunds(EntityManager em, User from, User to, double amnt) {
// note: it would be better practice to move the transaction demarcation
// code out of this method, but for the purposes of example...
Transaction trans = em.getTransaction ();
trans.begin ();
Transaction trans = em.getTransaction();
trans.begin();
try
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
trans.commit ();
from.decrementAccount(amnt);
to.incrementAccount(amnt);
trans.commit();
}
catch (RuntimeException re)
{
if (trans.isActive ())
trans.rollback (); // or could attempt to fix error and retry
if (trans.isActive())
trans.rollback(); // or could attempt to fix error and retry
throw re;
}
}

View File

@ -287,9 +287,7 @@ by the table below.
</row>
<row>
<entry colname="sup">
Relational and Non-Relational Stores
Relational and Non-Relational Stores
</entry>
<entry colname="ser">
No

View File

@ -22,7 +22,7 @@ javax.persistence Javadoc</ulink>
</listitem>
<listitem>
<para>
<ulink url="../../api/index.html">OpenJPA API Javadoc</ulink>
<ulink url="../apidocs/index.html">OpenJPA API Javadoc</ulink>
</para>
</listitem>
<listitem>

View File

@ -37,7 +37,7 @@
]>
<book id="manual">
<bookinfo>
<title>OpenJPA Developers Guide</title>
<title>OpenJPA User's Guide</title>
</bookinfo>
<part id="introduction">
@ -62,13 +62,16 @@
&jpa_overview_conclusion.xml;
</part>
<!--
### TUTORIAL
<part id="tutorials">
<title>Tutorials</title>
&jpa_tutorials.xml;
</part>
-->
<part id="ref_guide">
<title>OpenJPA <phrase>JPA</phrase> Reference Guide</title>
<title>Reference Guide</title>
&ref_guide_intro.xml;
&ref_guide_conf.xml;
&ref_guide_logging.xml;
@ -84,10 +87,12 @@
&ref_guide_optimization.xml;
</part>
<!--
<part id="samples_guide_part">
<title>OpenJPA <phrase>JPA</phrase> Samples</title>
<title>Samples</title>
&samples_guide.xml;
</part>
-->
&jpa_resources.xml;
&supported_databases.xml;

View File

@ -1,30 +1,27 @@
<chapter id="openjpa_intro">
<title>
OpenJPA
<phrase>
JPA
</phrase>
</title>
<indexterm zone="openjpa_intro">
<primary>
OpenJPA
<phrase>
JPA
</phrase>
</primary>
</indexterm>
<para>
OpenJPA is Apache's implementation of Sun's <phrase>Java Persistence API (JPA)
specification</phrase> for the transparent persistence of Java objects. This
document provides an overview of <phrase>the JPA standard</phrase> and technical
OpenJPA is Apache's implementation of Sun's Java Persistence API (JPA)
specification for the transparent persistence of Java objects. This
document provides an overview of the JPA standard and technical
details on the use of OpenJPA.
</para>
<!--
### TUTORIAL
<para>
To quickly get started with JPA, you may want to begin at
To quickly get started with OpenJPA, you may want to begin at
<xref linkend="jpa_tutorial"/>. If you would prefer to start with an
introduction to the concepts of JPA, begin with
introduction to the JPA specification, begin with
<xref linkend="jpa_overview_intro"/>.
</para>
-->
<section id="openjpa_intro_about">
<title>
About This Document
@ -36,25 +33,27 @@ This document is intended for OpenJPA users. It is divided into several parts:
<listitem>
<para>
The <link linkend="jpa_overview_intro">JPA Overview</link> describes the
fundamentals of JPA.
fundamentals of the JPA specification.
</para>
</listitem>
<!--
### TUTORIAL
<listitem>
<para>
In the <link linkend="tutorials">OpenJPA <phrase>JPA</phrase> Tutorials</link>
you will develop simple persistent applications using OpenJPA. Through the
In the <link linkend="tutorials">OpenJPA Tutorials</link> you will develop
simple persistent applications using OpenJPA. Through the
tutorials' hands-on approach, you will become comfortable with the core tools
and development processes under OpenJPA <phrase>JPA</phrase>.
and development processes under OpenJPA.
</para>
</listitem>
-->
<listitem>
<para>
The <link linkend="ref_guide_intro">OpenJPA <phrase>JPA</phrase> Reference Guide
</link> contains detailed documentation on all aspects of OpenJPA <phrase>JPA
</phrase>. Browse through this guide to familiarize yourself with the many
advanced features and customization opportunities OpenJPA provides. Later, you
can use the guide when you need details on a specific aspect of OpenJPA <phrase>
JPA</phrase>.
The <link linkend="ref_guide_intro">OpenJPA Reference Guide</link> contains
detailed documentation on all aspects of OpenJPA. Browse through this guide
to familiarize yourself with the many advanced features and customization
opportunities OpenJPA provides. Later, you can use the guide when you need
details on a specific aspect of OpenJPA.
</para>
</listitem>
</itemizedlist>

View File

@ -289,7 +289,8 @@ tips on how to use this package to extend OpenJPA's caching service yourself.
<para>
Rather than use the low-level <literal>org.apache.openjpa.datacache</literal>
package APIs, JPA users should typically access the data cache through OpenJPA's
high-level <ulink url="../../api/openjpa/persistence/StoreCache.html">
high-level
<ulink url="../apidocs/org/apache/openjpa/persistence/StoreCache.html">
<classname>org.apache.openjpa.persistence.StoreCache</classname></ulink> facade.
This facade has methods to pin and unpin records, evict data from the cache, and
more.
@ -309,7 +310,7 @@ corresponding persistent class, and dynamically delegates to that cache.
</para>
<para>
If you know that you want to access a certain data cache and no others, the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<methodname>OpenJPAEntityManagerFactory.getStoreCache(String name)</methodname>
</ulink> method returns a <classname>StoreCache</classname> interface to a
particular named data cache.
@ -381,8 +382,8 @@ cache.evict (Magazine.class, changedMag.getId ());
</example>
<para>
See the <classname>StoreCache</classname>
<ulink url="../../api/openjpa/persistence/StoreCache.html">Javadoc</ulink> for
information on additional functionality it provides. Also,
<ulink url="../apidocs/org/apache/openjpa/persistence/StoreCache.html">
Javadoc</ulink> for information on additional functionality it provides. Also,
<xref linkend="ref_guide_runtime"/> discusses OpenJPA's other extensions
to the standard set of JPA runtime interfaces.
</para>
@ -445,10 +446,10 @@ execution time is fully traversed.
</para>
<para>
OpenJPA exposes a high-level interface to the query cache through the
<ulink url="../../api/openjpa/persistence/QueryResultCache.html"><classname>
org.apache.openjpa.persistence.QueryResultCache</classname></ulink> class. You
can access this class through the <classname> OpenJPAEntityManagerFactory
</classname>.
<ulink url="../apidocs/org/apache/openjpa/persistence/QueryResultCache.html">
<classname>org.apache.openjpa.persistence.QueryResultCache</classname></ulink>
class. You can access this class through the <classname>
OpenJPAEntityManagerFactory</classname>.
</para>
<example id="ref_guide_cache_queryaccess">
<title>
@ -825,8 +826,8 @@ instead.
<listitem>
<para>
<literal>ClearOnClose</literal>: Whether the Tangosol named cache should be
completely cleared when the <phrase><classname>EntityManagerFactory</classname>
</phrase> is closed. Defaults to <literal>false</literal>.
completely cleared when the <classname>EntityManagerFactory</classname>
is closed. Defaults to <literal>false</literal>.
</para>
</listitem>
</itemizedlist>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@ turn.
Factory Deployment
</title>
<para>
OpenJPA offers several <phrase><classname>EntityManagerFactory</classname>
</phrase> deployment options.
OpenJPA offers several <classname>EntityManagerFactory</classname>
deployment options.
</para>
<section id="ref_guide_deploy_factory_standalone">
<title>
@ -39,12 +39,12 @@ The JPA Overview describes the <classname>javax.persistence.Persistence
<classname>Persistence</classname> to add additional <classname>
EntityManagerFactory</classname> creation methods. The <classname>
org.apache.openjpa.persistence.OpenJPAPersistence</classname> class
<ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html"> Javadoc
</ulink> details these extensions.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAPersistence.html">
Javadoc</ulink> details these extensions.
</para>
<para>
After obtaining the factory, you can cache it for all <phrase><classname>
EntityManager</classname></phrase> creation duties.
After obtaining the factory, you can cache it for all <classname>
EntityManager</classname> creation duties.
</para>
</section>
<section id="ref_guide_deploy_inject">

View File

@ -83,7 +83,7 @@ attributes for the <literal>config</literal> tag are defined by the
<classname>JDBCConfiguration</classname></ulink> bean methods. Note that
excluding the <literal>config</literal> element will cause the Ant task to use
the default system configuration mechanism, such as the configuration defined in
the <phrase><filename>org.apache.openjpa.xml</filename></phrase> file.
the <filename>org.apache.openjpa.xml</filename> file.
</para>
<para>
Following is an example of how to use the nested <literal>config</literal> tag

View File

@ -3,22 +3,25 @@
Introduction
</title>
<para>
OpenJPA <phrase>JPA</phrase> is a JDBC-based implementation of the JPA standard.
This document is a reference for the configuration and use of OpenJPA <phrase>
JPA</phrase>.
OpenJPA is a JDBC-based implementation of the JPA standard.
This document is a reference for the configuration and use of OpenJPA.
</para>
<section id="ref_guide_intro_audience">
<title>
Intended Audience
</title>
<para>
This document is intended for OpenJPA <phrase>JPA</phrase> developers. It
This document is intended for OpenJPA developers. It
assumes strong knowledge of Java, familiarity with the eXtensible Markup
Language (XML), and an understanding of JPA. If you are not familiar with JPA,
please read the <link linkend="jpa_overview_intro">JPA Overview</link> before
proceeding. We also strongly recommend taking OpenJPA's hands-on
proceeding.
<!--
### TUTORIAL
We also strongly recommend taking OpenJPA's hands-on
<link linkend="tutorials">tutorials</link> to get comfortable with OpenJPA
basics.
-->
</para>
<para>
Certain sections of this guide cover advanced topics such as custom

View File

@ -61,7 +61,7 @@ files the tools are running on. Detailed output is only available via the
logging category the tool belongs to, such as <literal>openjpa.Enhance</literal>
for the enhancer (see <xref linkend="ref_guide_pc_enhance"/>) or <literal>
openjpa.MetaData</literal> for the mapping tool (see
<xref linkend="ref_guide_mapping_mappingtool"/> ). This logging category
<xref linkend="ref_guide_mapping_mappingtool"/>). This logging category
is provided so that you can get a general idea of what a tool is doing without
having to manipulate logging settings that might also affect runtime behavior.
</para>
@ -129,19 +129,6 @@ level at execution time. Information about possible performance concerns will be
logged to the <literal>INFO</literal> level.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
remote
</primary>
<secondary>
log messages
</secondary>
</indexterm>
<literal>openjpa.Remote</literal>: Remote connection and execution messages.
</para>
</listitem>
<listitem>
<para>
<indexterm>
@ -209,7 +196,7 @@ Pretty-printing properties configuration might look like so:
<programlisting>
&lt;property name="openjpa.Log" value="SQL=TRACE"/&gt;
&lt;property name="openjpa.ConnectionFactoryProperties"
value="MaxActive=100, PrettyPrint=true, PrettyPrintLineLength=72"/&gt;
value="PrettyPrint=true, PrettyPrintLineLength=72"/&gt;
</programlisting>
</listitem>
<listitem>
@ -245,8 +232,8 @@ By default, OpenJPA uses a basic logging framework with the following output
format:
</para>
<para>
<literal>millis</literal><literal>level</literal> [ <literal>thread name
</literal> ] <literal>channel</literal> - <literal>message</literal>
<literal>millis</literal><literal>level</literal> [<literal>thread
name</literal>] <literal>channel</literal> - <literal>message</literal>
</para>
<para>
For example, when loading an application that uses OpenJPA, a message like the
@ -511,32 +498,28 @@ package com.xyz;
import org.apache.openjpa.lib.log.*;
public class CustomLogFactory
implements LogFactory
{
implements LogFactory {
private String _prefix = "CUSTOM LOG";
public void setPrefix (String prefix)
{
public void setPrefix (String prefix) {
_prefix = prefix;
}
public Log getLog (String channel)
{
public Log getLog(String channel) {
// Return a simple extension of AbstractLog that will log
// everything to the System.err stream. Note that this is
// roughly equivalent to OpenJPA's default logging behavior.
return new AbstractLog ()
{
protected boolean isEnabled (short logLevel)
{
return new AbstractLog() {
protected boolean isEnabled(short logLevel) {
// log all levels
return true;
}
protected void log (short type, String message, Throwable t)
{
protected void log (short type, String message, Throwable t) {
// just send everything to System.err
System.err.println (_prefix + ": " + type + ": "
System.err.println(_prefix + ": " + type + ": "
+ message + ": " + t);
}
};

View File

@ -955,7 +955,7 @@ schema that matches your object model.
OpenJPA relies on foreign key constraint information at runtime to order SQL
appropriately. Be sure to set your mapping defaults to reflect your existing
database constraints, or use explicit foreign key mappings as described in
<phrase><xref linkend="ref_guide_mapping_jpa_fk"/></phrase>.
<xref linkend="ref_guide_mapping_jpa_fk"/>.
</para>
</important>
<para>
@ -980,7 +980,7 @@ properties (though with different default values).
</listitem>
<listitem>
<para>
<phrase><literal>default</literal>:</phrase> This is an alias for the
<literal>default</literal>: This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.html">
<classname>org.apache.openjpa.jdbc.meta.MappingDefaultsImpl</classname></ulink>
class. This default implementation is highly configurable. It has the following
@ -2505,14 +2505,14 @@ OpenJPA recognizes the following class extensions.
<para>
This extension specifies how to eagerly fetch subclass state. It overrides the
global <link linkend="openjpa.jdbc.SubclassFetchMode"><literal>
openjpa.jdbc.SubclassFetchMode</literal></link> property. <phrase> Set the JPA
openjpa.jdbc.SubclassFetchMode</literal></link> property. Set the JPA
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/SubclassFetchMode.html">
<classname>org.apache.openjpa.persistence.jdbc.SubclassFetchMode</classname>
</ulink> annotation to a value from the
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
<literal>NONE</literal>.</phrase> See <xref linkend="ref_guide_perfpack_eager"/>
<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
for a discussion of eager fetching.
</para>
</section>
@ -2625,14 +2625,14 @@ OpenJPA recognizes the following field extensions.
<para>
This extension specifies how to eagerly fetch related objects. It overrides the
global <link linkend="openjpa.jdbc.EagerFetchMode"><literal>
openjpa.jdbc.EagerFetchMode</literal></link> property. <phrase>Set the JPA
openjpa.jdbc.EagerFetchMode</literal></link> property. Set the JPA
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/EagerFetchMode.html">
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchMode</classname>
</ulink> annotation to a value from the
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/EagerFetchType.html">
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname>
</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or
<literal>NONE</literal>.</phrase> See <xref linkend="ref_guide_perfpack_eager"/>
<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/>
for a discussion of eager fetching.
</para>
</section>
@ -2877,12 +2877,11 @@ concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats
</literal> package.
</para>
<para>
<phrase>The
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/Strategy.html">
The <ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/Strategy.html">
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
annotation allows you to declare a custom class mapping strategy in JPA mapping
metadata. Set the value of the annotation to the full class name of your custom
strategy.</phrase> You can configure your strategy class' bean properties using
strategy. You can configure your strategy class' bean properties using
OpenJPA's plugin syntax, detailed in <xref linkend="ref_guide_conf_plugins"/>
.
</para>
@ -3028,10 +3027,10 @@ defaults in detail.
<para>
Your other option is to explicitly install a custom value handler or strategy on
a particular field. To do so, specify the full name of your implementation class
in the proper mapping metadata extension. <phrase>OpenJPA includes the
in the proper mapping metadata extension. OpenJPA includes the
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/Strategy.html">
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink>
annotation.</phrase> You can configure the named strategy or handler's bean
annotation. You can configure the named strategy or handler's bean
properties in these extensions using OpenJPA's plugin format (see
<xref linkend="ref_guide_conf_plugins"/> ).
</para>

View File

@ -3,8 +3,8 @@
Metadata
</title>
<para>
The JPA Overview covers JPA metadata in <xref linkend="jpa_overview_meta"/>
. This chapter discusses OpenJPA's extensions to standard JPA metadata.
The JPA Overview covers JPA metadata in <xref linkend="jpa_overview_meta"/>.
This chapter discusses OpenJPA's extensions to standard JPA metadata.
</para>
<section id="ref_guide_meta_factory">
<title>
@ -24,14 +24,14 @@ The JPA Overview covers JPA metadata in <xref linkend="jpa_overview_meta"/>
<para>
The <link linkend="openjpa.MetaDataFactory"><literal>openjpa.MetaDataFactory
</literal></link> configuration property controls metadata loading and storing.
This property takes a plugin string (see <xref linkend="ref_guide_conf_plugins"/>
) describing a concrete
This property takes a plugin string (see
<xref linkend="ref_guide_conf_plugins"/>) describing a concrete
<ulink url="../apidocs/org/apache/openjpa/meta/MetaDataFactory.html">
<classname>org.apache.openjpa.meta.MetaDataFactory</classname></ulink>
implementation. A metadata factory can load mapping information as well as
persistence metadata, or it can leave mapping information to a separate
<emphasis>mapping factory</emphasis> (see
<xref linkend="ref_guide_mapping_factory"/> ). OpenJPA recognizes the
<xref linkend="ref_guide_mapping_factory"/>). OpenJPA recognizes the
following built-in metadata factories:
</para>
<itemizedlist>
@ -39,17 +39,20 @@ following built-in metadata factories:
<para>
<literal>jpa</literal>: Standard JPA metadata. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistenceMetaDataFactory.html">
<classname> org.apache.openjpa.persistence.PersistenceMetaDataFactory
</classname></ulink>.
<classname>
org.apache.openjpa.persistence.PersistenceMetaDataFactory</classname></ulink>.
</para>
</listitem>
</itemizedlist>
<para>
The standard metadata factories all accept the following properties for locating
persistent classes. Each property represents a different mechanism for locating
persistent types; you can choose the mechanism or combination of mechanisms that
are most convenient. See <xref linkend="ref_guide_pc_pcclasses"/> for a
discussion of when it is necessary to list your persistent classes.
JPA has built-in settings for listing your persistent classes, which
the <link linkend="jpa_overview_persistence_xml">JPA Overview</link> describes.
OpenJPA supports these JPA standard settings by translating them into its own
internal metadata factory properties. Each internal property represents a
different mechanism for locating persistent types; you can choose the mechanism
or combination of mechanisms that are most convenient. See
<xref linkend="ref_guide_pc_pcclasses"/> for a discussion of when it is
necessary to list your persistent classes.
</para>
<itemizedlist>
<listitem>
@ -61,22 +64,22 @@ persistent class names.
<listitem>
<para>
<literal>Resources</literal>: A semicolon-separated list of resource paths to
metadata files or jar archives. Each jar archive will be scanned for <phrase>
annotated JPA entities</phrase>.
metadata files or jar archives. Each jar archive will be scanned for
annotated JPA entities.
</para>
</listitem>
<listitem>
<para>
<literal>URLs</literal>: A semicolon-separated list of URLs of metadata files
or jar archives. Each jar archive will be scanned for <phrase>annotated JPA
entities</phrase>.
or jar archives. Each jar archive will be scanned for annotated JPA
entities.
</para>
</listitem>
<listitem>
<para>
<literal>ClasspathScan</literal>: A semicolon-separated list of directories or
jar archives listed in your classpath. Each directory and jar archive will be
scanned for <phrase>annotated JPA entities</phrase>.
scanned for annotated JPA entities.
</para>
</listitem>
</itemizedlist>
@ -85,7 +88,7 @@ scanned for <phrase>annotated JPA entities</phrase>.
Setting a Standard Metadata Factory
</title>
<programlisting>
&lt;property name="openjpa.MetaDataFactory" value="jpa"/&gt;
&lt;property name="openjpa.MetaDataFactory" value="jpa(ClasspathScan=build;lib.jar)"/&gt;
</programlisting>
</example>
<example id="ref_guide_meta_customfactoryex">
@ -227,160 +230,6 @@ annotation exists. For example, <xref linkend="ref_guide_mapping_jpa_columns"/>
to denote a persistent <classname>java.awt.Point</classname> field.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent_coll">
<title>
Persistent Collection Fields
</title>
<indexterm zone="ref_guide_meta_jpa_persistent_coll">
<primary>
persistent fields
</primary>
<secondary>
collection metadata
</secondary>
</indexterm>
<para>
JPA standardizes support for collections of entities with the <literal>
OneToMany</literal> and <literal>ManyToMany</literal> persistence strategies.
OpenJPA expands collection support to handle collections of simple types
(primitive wrappers, <classname>String</classname> s, etc), custom types, and
embedded objects.
</para>
<para>
The
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistentCollection.html">
<classname>org.apache.openjpa.persistence.PersistentCollection</classname>
</ulink> metadata annotation represents a persistent collection field. It has
the following properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>Class elementType</literal>: The class of the collection elements.
This information is usually taken from the parameterized collection element
type. You must supply it explicitly, however, if your field isn't a
parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the collection eagerly or
lazily. Corresponds exactly to the same-named property of standard JPA
annotations such as <link linkend="jpa_overview_meta_basic"><classname> Basic
</classname></link>. Defaults to <literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>String mappedBy</literal>: Names the field in the related entity that
maps this bidirectional relation. Corresponds to the same-named property of
standard JPA annotations such as <link linkend="jpa_overview_meta_manytomany">
<classname> ManyToMany</classname></link>.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] elementCascade</literal>: Array of enum values defining
cascade behavior for the collection elements. Corresponds exactly to the
<literal>cascade</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytomany"><classname>ManyToMany</classname>
</link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>boolean elementEmbedded</literal>: Set this property to <literal>true
</literal> if the elements are stored as embedded objects.
</para>
</listitem>
</itemizedlist>
<para>
<xref linkend="ref_guide_mapping_jpa_coll"/> contains several examples of
using <classname>PersistentCollection</classname> to mark non-standard
collection fields persistent.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent_map">
<title>
Persistent Map Fields
</title>
<indexterm zone="ref_guide_meta_jpa_persistent_map">
<primary>
persistent fields
</primary>
<secondary>
map metadata
</secondary>
</indexterm>
<para>
JPA has limited support for maps. OpenJPA introduces the
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistentMap.html">
<classname>org.apache.openjpa.persistence.PersistentMap</classname></ulink>
metadata annotation to represent a persistent map field. It has the following
properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>Class keyType</literal>: The class of the map keys. This information
is usually taken from the parameterized map key type. You must supply it
explicitly, however, if your field isn't a parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>Class elementType</literal>: The class of the map values. This
information is usually taken from the parameterized map value type. You must
supply it explicitly, however, if your field isn't a parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the collection eagerly or
lazily. Corresponds exactly to the same-named property of standard JPA
annotations such as <link linkend="jpa_overview_meta_basic"><classname> Basic
</classname></link>. Defaults to <literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] keyCascade</literal>: Array of enum values defining
cascade behavior for the map keys. Corresponds exactly to the <literal>cascade
</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>ManyToOne</classname>
</link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] elementCascade</literal>: Array of enum values defining
cascade behavior for the map values. Corresponds exactly to the <literal>
cascade</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>ManyToOne</classname>
</link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>boolean keyEmbedded</literal>: Set this property to <literal>true
</literal> if the map keys are stored as embedded objects.
</para>
</listitem>
<listitem>
<para>
<literal>boolean elementEmbedded</literal>: Set this property to <literal>true
</literal> if the map values are stored as embedded objects.
</para>
</listitem>
</itemizedlist>
<para>
Map keys and values in OpenJPA can be entities, simple types (primitive
wrappers, <classname>String</classname> s, etc), custom types, or embedded
objects. <xref linkend="ref_guide_mapping_jpa_map"/> contains several
examples of using <classname>PersistentMap</classname> to annotate persistent
map fields.
</para>
</section>
</section>
<section id="ref_guide_meta_ext">
<title>
@ -477,15 +326,6 @@ other properties are ignored.
</listitem>
<listitem>
<para>
<literal>String name</literal>: Place data for instances of the class in a
named cache. By default, instance data is placed in the same cache as superclass
data, or the default cache configured through the
<link linkend="openjpa.DataCache"><literal> openjpa.DataCache</literal></link>
configuration property for base classes.
</para>
</listitem>
<listitem>
<para>
<literal>int timeout</literal>: The number of milliseconds data for the class
remains valid. Use -1 for no timeout. Defaults to the
<link linkend="openjpa.DataCacheTimeout"><literal> openjpa.DataCacheTimeout
@ -669,74 +509,14 @@ annotation in particular.
</seealso>
</indexterm>
<para>
This boolean extension, denoted by <phrase> the JPA
This boolean extension, denoted by the OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/LRS.html"><classname>
org.apache.openjpa.persistence.LRS</classname></ulink> annotation,</phrase>
org.apache.openjpa.persistence.LRS</classname></ulink> annotation,
indicates that a field should use OpenJPA's special large result set collection
or map proxies. A complete description of large result set proxies is available
in <xref linkend="ref_guide_pc_scos_proxy_lrs"/>.
</para>
</section>
<section id="order-by">
<title>
Order-By
</title>
<indexterm zone="order-by">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
order-by
</tertiary>
</indexterm>
<para>
<phrase> The JPA Overview's <xref linkend="jpa_overview_meta_orderby"/>
describes JPA's <literal>OrderBy</literal> annotation for loading the elements
of collection fields in a prescribed order.</phrase> Ordering syntax is as
follows:
</para>
<programlisting>
#element|&lt;field name&gt;[ asc|ascending|desc|descending][, ...]
</programlisting>
<para>
The token <literal>#element</literal> represents the element value. Simple
element types such as strings and primitive wrappers are sorted based on their
natural ordering. If the collection holds persistent objects, its elements are
sorted based on the natural ordering of the objects' primary key values. By
substituting a field name for the <literal> #element</literal> token, you can
order a collection of persistent objects by an arbitrary field in the related
type, rather than by primary key.
</para>
<para>
The field name or <literal>#element</literal> token may be followed by the
keywords <literal>asc/ascending</literal> or <literal>desc/descending</literal>
in either all-upper or all-lower case to mandate ascending and descending order.
If the direction is omitted, OpenJPA defaults to ascending order.
</para>
<para>
Note that the defined ordering is only applied when the collection is loaded
from the datastore. It is not maintained by OpenJPA as you modify the collection
in memory.
</para>
<para>
The following ordering string orders a collection by its element values in
descending order:
</para>
<programlisting>
"#element desc"
</programlisting>
<para>
The following ordering string orders a collection of <classname>Author
</classname> objects by each author's last name in ascending order. If two last
names are equal, the authors are ordered by first name in ascending order.
</para>
<programlisting>
"firstName, lastName"
</programlisting>
</section>
<section id="inverse-logical">
<title>
Inverse-Logical
@ -757,10 +537,10 @@ names are equal, the authors are ordered by first name in ascending order.
</indexterm>
<para>
This extension names the inverse field in a logical bidirectional relation.
<phrase> To create a logical bidrectional relation in OpenJPA, use the
To create a logical bidrectional relation in OpenJPA, use the
<ulink url="../apidocs/org/apache/openjpa/persistence/InverseLogical.html">
<classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
annotation.</phrase> We discuss logical bidirectional relations and this
annotation. We discuss logical bidirectional relations and this
extension in detail in <xref linkend="ref_guide_inverses"/>.
</para>
</section>
@ -798,7 +578,7 @@ existing persistent objects; new object fields are always writeable.
To mark a field read-only in JPA metadata, set the
<ulink url="../apidocs/org/apache/openjpa/persistence/ReadOnly.html">
<classname>org.apache.openjpa.persistence.ReadOnly</classname></ulink>
annotation to a
annotation to an
<ulink url="../apidocs/org/apache/openjpa/persistence/UpdateAction.html">
<classname>org.apache.openjpa.persistence.UpdateAction</classname></ulink> enum
value. The <classname>UpdateAction</classname> enum includes:
@ -876,7 +656,7 @@ non-interface, unrecognized field types, which are all assigned level 3 support.
<para>
With OpenJPA's type family of metadata extensions, you can control the level of
support given to your unknown/interface-typed fields. Setting the value of this
extension to <phrase><classname>Entity</classname></phrase> indicates that the
extension to <classname>Entity</classname> indicates that the
field value will always be some persistent object, and gives level 2 support.
Setting the value of this extension to the class of a concrete persistent type
is even better; it gives you level 1 support (just as if you had declared your
@ -934,10 +714,10 @@ org.apache.openjpa.persistence.KeyType</classname></ulink>
</seealso>
</indexterm>
<para>
The <phrase> JPA
The OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/Externalizer.html">
<classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
annotation</phrase> names a method to transform a field value into a value of
annotation names a method to transform a field value into a value of
another type. See <xref linkend="ref_guide_pc_extern"/> for details.
</para>
</section>
@ -960,9 +740,9 @@ another type. See <xref linkend="ref_guide_pc_extern"/> for details.
</seealso>
</indexterm>
<para>
The <phrase> JPA
The OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/Factory.html"><classname>
org.apache.openjpa.persistence.Factory</classname></ulink> annotation</phrase>
org.apache.openjpa.persistence.Factory</classname></ulink> annotation
names a method to re-create a field value from its externalized form. See
<xref linkend="ref_guide_pc_extern"/> for details.
</para>
@ -986,10 +766,10 @@ names a method to re-create a field value from its externalized form. See
</seealso>
</indexterm>
<para>
The <phrase> JPA
The OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/ExternalValues.html">
<classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
annotation</phrase> declares values for transformation of simple fields to
annotation declares values for transformation of simple fields to
different constant values in the datastore. See
<xref linkend="ref_guide_pc_extern_values"/> for details.
</para>
@ -1021,10 +801,6 @@ public class Magazine
@Type(int.class)
private boolean weekly;
@PersistentCollection
@OrderBy("#element DESC")
private List&lt;String&gt; subtitles;
...
}
</programlisting>

View File

@ -186,12 +186,10 @@ or deletes.
flushes during your transaction to reduce its memory
requirements. See the Javadoc:
<phrase>
<ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setLargeTransaction
</ulink>
</phrase>
</ulink>
@ -203,9 +201,9 @@ If your transaction will visit objects that you know are very unlikely to be
accessed by other transactions, for example an exhaustive report run only once a
month, you can turn off population of the data cache so that the transaction
doesn't fill the entire data cache with objects that won't be accessed again.
Again, see the Javadoc: <phrase>
<ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setPopulateDataCache</ulink></phrase>
Again, see the Javadoc:
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setPopulateDataCache</ulink>
</para>
</entry>
</row>

View File

@ -57,14 +57,14 @@ may return incorrect results.
<listitem>
<para>
If you configure OpenJPA to create the needed database schema on startup (see
<xref linkend="ref_guide_mapping_synch"/> ), OpenJPA must know all of your
<xref linkend="ref_guide_mapping_synch"/>), OpenJPA must know all of your
persistent classes up-front.
</para>
</listitem>
</itemizedlist>
<para>
When any of these conditions are a factor in your JPA application, use the
<literal>class</literal>, <literal> mapping-file</literal>, and <literal>
<literal>class</literal>, <literal>mapping-file</literal>, and <literal>
jar-file</literal> elements of JPA's standard XML format to list your persistent
classes. See <xref linkend="jpa_overview_persistence_xml"/> for details.
</para>
@ -101,20 +101,19 @@ persistent classes after you have written them. The enhancer post-processes the
bytecode generated by your Java compiler, adding the necessary fields and
methods to implement the required persistence features. This bytecode
modification perfectly preserves the line numbers in stack traces and is
compatible with Java debuggers. <phrase> In fact, the only change to debugging
compatible with Java debuggers. In fact, the only change to debugging
is that the persistent setter and getter methods of entity classes using
property access will be prefixed with <literal>pc</literal> in stack traces and
step-throughs. For example, if your entity has a <methodname>getId</methodname>
method for persistent property <literal>id</literal>, and that method throws an
exception, the stack trace will report the exception from method <methodname>
pcgetId</methodname>. The line numbers, however, will correctly correspond to
the <methodname>getId</methodname> method in your source file.</phrase>
the <methodname>getId</methodname> method in your source file.
</para>
<mediaobject>
<imageobject>
<!-- PNG image data, 509 x 133 (see README) -->
<imagedata fileref="img/enhancement.png" width="339px"/>
</imageobject>
</mediaobject>
<para>
@ -139,13 +138,13 @@ are loaded into the JVM. The following sections describe each option.
</indexterm>
<para>
The enhancer can be invoked at build time
via the Java tool,
<classname>org.apache.openjpa.enhance.PCEnhancer</classname>.
via its Java class, <classname>
org.apache.openjpa.enhance.PCEnhancer</classname>.
</para>
<note>
<para>
You can also enhance via Ant; see <xref linkend="ref_guide_integration_enhance"/>
.
You can also enhance via Ant; see
<xref linkend="ref_guide_integration_enhance"/>.
</para>
</note>
<example id="ref_guide_pc_enhance_enhancer">
@ -182,8 +181,8 @@ not obeying the restrictions placed on property access. Defaults to false.
<literal>-addDefaultConstructor/-adc &lt;true/t | false/f&gt;</literal>: The
spec requires that all persistent classes define a no-arg constructor. This flag
tells the enhancer whether to add a protected no-arg constructor to any
persistent classes that don't already have one. Defaults to <literal>true
</literal>.
persistent classes that don't already have one. Defaults to <literal>
true</literal>.
</para>
</listitem>
<listitem>
@ -218,8 +217,7 @@ The <filename>.class</filename> file of a class.
</itemizedlist>
<para>
If you do not supply any arguments to the enhancer, it will run on the classes
in your persistent class list (see <xref linkend="ref_guide_pc_pcclasses"/>
).
in your persistent class list (see <xref linkend="ref_guide_pc_pcclasses"/>).
</para>
<para>
You can run the enhancer over classes that have already been enhanced, in which
@ -286,38 +284,30 @@ are invoked prior to your application's <methodname>main</methodname> method.
OpenJPA's agent uses JVM hooks to intercept all class loading to enhance classes
that have persistence metadata before the JVM loads them.
</para>
<note>
<para>
Java agents are new to Java 5; if you are using a previous Java version, you
must use OpenJPA's <link linkend="ref_guide_pc_enhance_build">build-time
enhancement</link> option.
</para>
</note>
<para>
Searching for metadata for every class loaded by the JVM can slow application
initialization. One way to speed things up is to take advantage of the optional
persistent class list described in <xref linkend="ref_guide_pc_pcclasses"/>
. If you declare a persistent class list, OpenJPA will only search for
persistent class list described in <xref linkend="ref_guide_pc_pcclasses"/>. If
you declare a persistent class list, OpenJPA will only search for
metadata for classes in that list.
</para>
<para>
To employ the OpenJPA agent, invoke <literal>java</literal> with the <literal>
-javaagent</literal> set to the path to your <filename>org.apache.openjpa.jar
</filename> or <filename>openjpa-runtime.jar</filename> file.
-javaagent</literal> set to the path to your OpenJPA jar file.
</para>
<example id="ref_guide_pc_enhance_runtime_ex">
<title>
Using the OpenJPA Agent for Runtime Enhancement
</title>
<programlisting>
java -javaagent:/home/dev/openjpa/lib/org.apache.openjpa.jar com.xyz.Main
java -javaagent:/home/dev/openjpa/lib/openjpa.jar com.xyz.Main
</programlisting>
</example>
<para>
You can pass settings to the agent using OpenJPA's plugin syntax (see
<xref linkend="ref_guide_conf_plugins"/> ). The agent accepts the long
form of any of the standard configuration options (
<xref linkend="ref_guide_conf_devtools"/> ). It also accepts the following
<xref linkend="ref_guide_conf_plugins"/>). The agent accepts the long
form of any of the standard configuration options
(<xref linkend="ref_guide_conf_devtools"/> ). It also accepts the following
options, the first three of which correspond exactly to to the same-named
options of the enhancer tool described in
<xref linkend="ref_guide_pc_enhance_build"/>:
@ -330,11 +320,6 @@ options of the enhancer tool described in
</listitem>
<listitem>
<para>
<literal>jdoEnhance</literal>
</para>
</listitem>
<listitem>
<para>
<literal>enforcePropertyRestrictions</literal>
</para>
</listitem>
@ -353,7 +338,7 @@ accordingly. This may slow down class load times significantly.
Passing Options to the OpenJPA Agent
</title>
<programlisting>
java -javaagent:/home/dev/openjpa/lib/org.apache.openjpa.jar=jdoEnhance=true,addDefaultConstructor=false com.xyz.Main
java -javaagent:/home/dev/openjpa/lib/openjpa.jar=addDefaultConstructor=false com.xyz.Main
</programlisting>
</example>
</section>
@ -420,7 +405,7 @@ described in <xref linkend="jpa_overview_meta_id"/> of the JPA Overview.
</para>
<para>
To retrieve the identity value of a datastore identity entity, use the
<methodname>OpenJPAEntityManager.getObjectId (Object entity)</methodname>
<methodname>OpenJPAEntityManager.getObjectId(Object entity)</methodname>
method. See <xref linkend="ref_guide_runtime_em"/> for more information on
the <classname>OpenJPAEntityManager</classname>.
</para>
@ -433,8 +418,8 @@ import org.apache.openjpa.persistence.*;
@Entity
@DataStoreId
public class LineItem
{
public class LineItem {
... no @Id fields declared ...
}
</programlisting>
@ -491,7 +476,7 @@ record.
</indexterm>
<para>
If you choose to use application identity, you may want to take advantage of
OpenJPA <phrase>JPA</phrase>'s application identity tool. The application
OpenJPA's application identity tool. The application
identity tool generates Java code implementing the identity class for any
persistent type using application identity. The code satisfies all the
requirements the specification places on identity classes. You can use it as-is,
@ -513,7 +498,7 @@ generated identity class. Once the application identity tool has generated the
class code, you can set the <literal>@IdClass</literal> annotation.
</para>
<para>
The application identity tool can be invoked via the Java class,
The application identity tool can be invoked via its Java class,
<ulink url="../apidocs/org/apache/openjpa/enhance/ApplicationIdTool">
<classname>org.apache.openjpa.enhance.ApplicationIdTool</classname></ulink>.
</para>
@ -534,7 +519,7 @@ java org.apache.openjpa.enhance.ApplicationIdTool -s Id Magazine.java
<para>
The application identity tool accepts the standard set of command-line arguments
defined by the configuration framework (see
<xref linkend="ref_guide_conf_devtools"/> ), including code formatting
<xref linkend="ref_guide_conf_devtools"/>), including code formatting
flags described in <xref linkend="ref_guide_conf_devtools_format"/>. It
also accepts the following arguments:
</para>
@ -605,8 +590,7 @@ The <filename>.class</filename> file of a persistent class.
</itemizedlist>
<para>
If you do not supply any arguments to the tool, it will act on the classes in
your persistent classes list (see <xref linkend="ref_guide_pc_pcclasses"/>
).
your persistent classes list (see <xref linkend="ref_guide_pc_pcclasses"/>).
</para>
</section>
<section id="ref_guide_pc_oid_pkgen_autoinc">
@ -666,14 +650,6 @@ non-primary key auto-increment columns, and may allow more than one per table.
See your database documentation for details.
</para>
</listitem>
<listitem>
<para>
Statements inserting into tables with auto-increment / identity columns cannot
be batched. After each insert, OpenJPA must go back to the database to retrieve
the last inserted auto-increment value to set back in the persistent object.
This can have a negative impact on performance.
</para>
</listitem>
</orderedlist>
</section>
</section>
@ -696,11 +672,10 @@ use the <literal>mappedBy</literal> annotation attribute to form bidirectional
relations that also share datastore storage in JPA.
</para>
<para>
OpenJPA also allows you to define purely logical bidirectional relations.
<phrase> The
OpenJPA also allows you to define purely logical bidirectional relations. The
<ulink url="../apidocs/org/apache/openjpa/persistence/InverseLogical.html">
<classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
annotation names a logical inverse in JPA metadata.</phrase>
annotation names a logical inverse in JPA metadata.
</para>
<example id="ref_guide_inverses_logicalex">
<title>
@ -717,8 +692,8 @@ inverse of both fields.
import org.apache.openjpa.persistence.*;
@Entity
public class Magazine
{
public class Magazine {
@OneToOne
private Photograph coverPhoto;
@ -726,26 +701,14 @@ public class Magazine
}
@Entity
public class Photograph
{
public class Photograph {
@OneToOne
@InverseLogical("coverPhoto")
private Magazine mag;
...
}
</programlisting>
<programlisting>
&lt;class name="Magazine"&gt;
&lt;field name="coverPhoto"/&gt;
...
&lt;/class&gt;
&lt;class name="Photograph"&gt;
&lt;field name="mag"&gt;
&lt;extension vendor-name="openjpa" key="inverse-logical" value="coverPhoto"/&gt;
&lt;/field&gt;
...
&lt;/class&gt;
</programlisting>
</example>
<para>
@ -878,19 +841,18 @@ employeesBySal</literal> and <literal>departments</literal> are persistent
fields in the class below.
</para>
<programlisting>
public class Company
{
public class Company {
// OpenJPA will detect the custom comparator in the initial field value
// and use it whenever loading data from the database into this field
private Collection employeesBySal = new TreeSet (new SalaryComparator ());
private Collection employeesBySal = new TreeSet(new SalaryComparator());
private Map departments;
public Company
{
public Company {
// or we can initialize fields in our no-args constructor; even though
// this field is declared type Map, OpenJPA will detect that it's actually
// a TreeMap and use natural ordering for loaded data
departments = new TreeMap ();
// this field is declared type Map, OpenJPA will detect that it's
// actually a TreeMap and use natural ordering for loaded data
departments = new TreeMap();
}
// rest of class definition...
@ -978,7 +940,7 @@ OpenJPA smart proxies by using fields of type <classname>java.util.Set
</classname>, <classname>java.util.TreeSet</classname>, and <classname>
java.util.HashSet</classname> for your collections whenever possible. Smart
proxies for these types are more efficient than proxies for <classname>List
</classname> s. You can also design your own smart proxies to further optimize
</classname>s. You can also design your own smart proxies to further optimize
OpenJPA for your usage patterns. See the section on
<link linkend="ref_guide_pc_scos_proxy_custom">custom proxies</link> for
details.
@ -1019,7 +981,7 @@ large result set collection will perform a <literal> SELECT COUNT(*)</literal>
query with the proper <literal>WHERE</literal> conditions to find out if the
given element exists in the database's record of the collection. Similarly, each
time you obtain an iterator OpenJPA performs the proper query using the current
<link linkend="ref_guide_dbsetup_lrs"> large result set settings</link>, as
<link linkend="ref_guide_dbsetup_lrs">large result set settings</link>, as
discussed in the <link linkend="ref_guide_dbsetup">JDBC</link> chapter. As you
invoke <methodname>Iterator.next</methodname>, OpenJPA instantiates the result
objects on-demand.
@ -1038,11 +1000,11 @@ import org.apache.openjpa.persistence.*;
...
Collection employees = company.getEmployees (); // employees is a lrs collection
Iterator itr = employees.iterator ();
while (itr.hasNext ())
process ((Employee) itr.next ());
OpenJPAPersistence.close (itr);
Collection employees = company.getEmployees(); // employees is a lrs collection
Iterator itr = employees.iterator();
while (itr.hasNext())
process((Employee) itr.next());
OpenJPAPersistence.close(itr);
</programlisting>
</example>
<para>
@ -1052,10 +1014,10 @@ which it uses to make sure the proper results are always returned from
collection and map methods, and to update the field's database record on commit.
</para>
<para>
<phrase> In order to use large result set proxies in JPA, add the
In order to use large result set proxies in JPA, add the
<ulink url="../apidocs/org/apache/openjpa/persistence/LRS.html"><classname>
org.apache.openjpa.persistence.LRS</classname></ulink> annotation to the
persistent field.</phrase>
persistent field.
</para>
<para>
The following restrictions apply to large result set fields:
@ -1071,8 +1033,8 @@ concrete collection or map class.
</listitem>
<listitem>
<para>
The field cannot have an externalizer (see <xref linkend="ref_guide_pc_extern"/>
).
The field cannot have an externalizer (see
<xref linkend="ref_guide_pc_extern"/>).
</para>
</listitem>
<listitem>
@ -1082,9 +1044,9 @@ cannot be transferred from one persistent field to another. The following code
would result in an error on commit:
</para>
<programlisting>
Collection employees = company.getEmployees () // employees is a lrs collection
company.setEmployees (null);
anotherCompany.setEmployees (employees);
Collection employees = company.getEmployees() // employees is a lrs collection
company.setEmployees(null);
anotherCompany.setEmployees(employees);
</programlisting>
</listitem>
</itemizedlist>
@ -1096,8 +1058,8 @@ anotherCompany.setEmployees (employees);
import org.apache.openjpa.persistence.*;
@Entity
public class Company
{
public class Company {
@ManyToMany
@LRS private Collection&lt;Employee&gt; employees;
@ -1132,7 +1094,7 @@ OpenJPA manages proxies through the
org.apache.openjpa.util.ProxyManager</classname></ulink> interface. OpenJPA
includes a default proxy manager, the <classname>
org.apache.openjpa.util.ProxyManagerImpl</classname> (with a plugin alias name
of <literal>default</literal> ), that will meet the needs of most users. The
of <literal>default</literal>), that will meet the needs of most users. The
default proxy manager understands the following configuration properties:
</para>
<itemizedlist>
@ -1203,10 +1165,10 @@ JPA cannot have externalizers.
</para>
</note>
<para>
The <phrase> JPA
The OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/Externalizer.html">
<classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
annotation</phrase> sets the name of a method that will be invoked to convert
annotation sets the name of a method that will be invoked to convert
the field into its external form for database storage. You can specify either
the name of a non-static method, which will be invoked on the field value, or a
static method, which will be invoked with the field value as a parameter. Each
@ -1235,10 +1197,10 @@ their corresponding metadata extensions.
<thead>
<row>
<entry colname="method">
Method
Method
</entry>
<entry colname="extension">
Extension
Extension
</entry>
</row>
</thead>
@ -1246,64 +1208,48 @@ their corresponding metadata extensions.
<row>
<entry colname="method">
<literal>
public String CustomType.toString()
public String CustomType.toString()
</literal>
</entry>
<entry colname="extension">
<literal>
@Externalizer("toString")
@Externalizer("toString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public String CustomType.toString(StoreContext ctx)
public String CustomType.toString(StoreContext ctx)
</literal>
</entry>
<entry colname="extension">
<literal>
@Externalizer("toString")
@Externalizer("toString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static String AnyClass.toString(CustomType ct)
public static String AnyClass.toString(CustomType ct)
</literal>
</entry>
<entry colname="extension">
<literal>
@Externalizer("AnyClass.toString")
@Externalizer("AnyClass.toString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static String AnyClass.toString(CustomType ct, StoreContext ctx)
public static String AnyClass.toString(CustomType ct, StoreContext ctx)
</literal>
</entry>
<entry colname="extension">
<literal>
@Externalizer("AnyClass.toString")
@Externalizer("AnyClass.toString")
</literal>
</entry>
</row>
@ -1311,9 +1257,9 @@ their corresponding metadata extensions.
</tgroup>
</table>
<para>
The <phrase> JPA
The OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/Factory.html"><classname>
org.apache.openjpa.persistence.Factory</classname></ulink> annotation</phrase>
org.apache.openjpa.persistence.Factory</classname></ulink> annotation
contains the name of a method that will be invoked to instantiate the field from
the external form stored in the database. Specify a static method name. The
method will will be invoked with the externalized value and must return an
@ -1335,16 +1281,14 @@ corresponding metadata extensions.
</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="method"/>
<colspec colname="extension"/>
<thead>
<row>
<entry colname="method">
Method
Method
</entry>
<entry colname="extension">
Extension
Extension
</entry>
</row>
</thead>
@ -1352,78 +1296,58 @@ corresponding metadata extensions.
<row>
<entry colname="method">
<literal>
public CustomType(String str)
public CustomType(String str)
</literal>
</entry>
<entry colname="extension">
none
none
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static CustomType CustomType.fromString(String str)
public static CustomType CustomType.fromString(String str)
</literal>
</entry>
<entry colname="extension">
<literal>
@Factory("fromString")
@Factory("fromString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static CustomType CustomType.fromString(String str, StoreContext ctx)
public static CustomType CustomType.fromString(String str, StoreContext ctx)
</literal>
</entry>
<entry colname="extension">
<literal>
@Factory("fromString")
@Factory("fromString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static CustomType AnyClass.fromString(String str)
public static CustomType AnyClass.fromString(String str)
</literal>
</entry>
<entry colname="extension">
<literal>
@Factory("AnyClass.fromString")
@Factory("AnyClass.fromString")
</literal>
</entry>
</row>
<row>
<entry colname="method">
<literal>
public static CustomType AnyClass.fromString(String str, StoreContext ctx)
public static CustomType AnyClass.fromString(String str, StoreContext ctx)
</literal>
</entry>
<entry colname="extension">
<literal>
@Factory("AnyClass.fromString")
@Factory("AnyClass.fromString")
</literal>
</entry>
</row>
@ -1432,24 +1356,19 @@ corresponding metadata extensions.
</table>
<para>
If your externalized field is not a standard persistent type, you must
explicitly mark it persistent. <phrase> In JPA, you can force a persistent field
explicitly mark it persistent. In OpenJPA, you can force a persistent field
by annotating it with <link linkend="ref_guide_meta_jpa_persistent"><classname>
org.apache.openjpa.persistence.Persistent</classname></link> annotation.
</phrase>
</para>
<note>
<para>
If your custom field type is mutable and is not a standard collection, map, or
date class, OpenJPA will not be able to detect changes to the field. You must
mark the field dirty manully, or create a custom field proxy.
</para>
<para>
<phrase> See
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
mark the field dirty manually, or create a custom field proxy.
See
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<methodname>OpenJPAEntityManager.dirty</methodname></ulink> for how to mark a
field dirty manually in JPA.</phrase>
</para>
<para>
field dirty manually in JPA.
See <xref linkend="ref_guide_pc_scos_proxy"/> for a discussion of proxies.
</para>
</note>
@ -1458,13 +1377,13 @@ You can externalize a field to virtually any value that is supported by
OpenJPA's field mappings (embedded relations are the exception; you must declare
your field to be a persistence-capable type in order to embed it). This means
that a field can externalize to something as simple as a primitive, something as
complex as a collection or map of persistence-capable objects, or anything in
complex as a collection or map of entities, or anything in
between. If you do choose to externalize to a collection or map, OpenJPA
recognizes a family of metadata extensions for specying type information for the
externalized form of your fields - see <xref linkend="type"/>. If the
external form of your field is a persistence-capable object, or contains
persistence-capable objects, OpenJPA will correctly include the objects in its
persistence-by-reachability algorithms and its delete-dependent algorithms.
external form of your field is an entity object or contains entities, OpenJPA
will correctly include the objects in its persistence-by-reachability
algorithms and its delete-dependent algorithms.
</para>
<para>
The example below demonstrates a few forms of externalization.
@ -1477,8 +1396,8 @@ The example below demonstrates a few forms of externalization.
import org.apache.openjpa.persistence.*;
@Entity
public class Magazine
{
public class Magazine {
// use Class.getName and Class.forName to go to/from strings
@Persistent
@Externalizer("getName")
@ -1491,22 +1410,19 @@ public class Magazine
@Externalizer("toExternalForm")
private URL url;
// use our custom methods; notice how we use the KeyType and ElementType
// annotations to specify the metadata for our externalized map
// use our custom methods
@Persistent
@Externalizer("Magazine.mapFromCustomType")
@Factory("Magazine.mapToCustomType")
@KeyType(String.class) @ElementType(String.class)
@Externalizer("Magazine.authorsFromCustomType")
@Factory("Magazine.authorsToCustomType")
@ElementType(Author.class)
private CustomType customType;
public static Map mapFromCustomType (CustomType customType)
{
... logic to pack custom type into a map ...
public static Collection authorsFromCustomType(CustomType customType) {
... logic to pack custom type into a list of authors ...
}
public static CustomType mapToCustomType (Map map)
{
... logic to create custom type from a map ...
public static CustomType authorsToCustomType (Collection authors) {
... logic to create custom type from a collection of authors ...
}
...
@ -1545,13 +1461,13 @@ previous example.
</para>
<programlisting>
// you can query using parameters
Query q = em.createQuery ("select m from Magazine m where m.url = :u");
q.setParameter ("u", new URL ("http://www.solarmetric.com"));
List results = q.getResultList ();
Query q = em.createQuery("select m from Magazine m where m.url = :u");
q.setParameter("u", new URL("http://www.solarmetric.com"));
List results = q.getResultList();
// or as a shortcut, you can use the externalized form directly
q = em.createQuery ("select m from Magazine m where m.url = 'http://www.solarmetric.com'");
results = q.getResultList ();
q = em.createQuery("select m from Magazine m where m.url = 'http://www.solarmetric.com'");
results = q.getResultList();
</programlisting>
</example>
<section id="ref_guide_pc_extern_values">
@ -1581,10 +1497,10 @@ External values supports translation of pre-defined simple types (primitives,
primitive wrappers, and Strings), to other pre-defined simple values.
</para>
<para>
Use the <phrase> JPA
Use the OpenJPA
<ulink url="../apidocs/org/apache/openjpa/persistence/ExternalValues.html">
<classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
annotation</phrase> to define external value translations. The values are
annotation to define external value translations. The values are
defined in a format similar to that of <link linkend="ref_guide_conf_plugins">
configuration plugins</link>, except that the value pairs represent Java and
datastore values. To convert the Java boolean values of <literal>true</literal>
@ -1594,9 +1510,9 @@ true=T,false=F</literal>.
</para>
<para>
If the type of the datastore value is different from the field's type, use the
<phrase> JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Type.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/Type.html">
<classname>org.apache.openjpa.persistence.Type</classname></ulink> annotation
</phrase> to define the datastore type.
to define the datastore type.
</para>
<example id="externvalues_ex">
<title>
@ -1607,8 +1523,8 @@ This example uses external value translation to transform a string field to an
integer in the database.
</para>
<programlisting>
public class Magazine
{
public class Magazine {
@ExternalValues({"SMALL=5", "MEDIUM=8", "LARGE=10"})
@Type(int.class)
private String sizeWidth;
@ -1746,8 +1662,7 @@ import org.apache.openjpa.persistence.*;
}),
...
})
public class Magazine
{
public class Magazine {
...
}
</programlisting>
@ -1787,8 +1702,8 @@ import org.apache.openjpa.persistence.*;
}),
...
})
public class Magazine
{
public class Magazine {
@ManyToOne(fetch=FetchType.LAZY)
@LoadFetchGroup("detail")
private Publisher publisher;
@ -1844,25 +1759,25 @@ the fetch depth to something less than the configured maximum.
OpenJPA's <classname>OpenJPAEntityManager</classname> and <classname>
OpenJPAQuery</classname> extensions to the standard <classname>EntityManager
</classname> and <classname>Query</classname> interfaces provide access to a
<ulink url="../../api/openjpa/persistence/FetchPlan.html"><classname>
org.apache.openjpa.persistence.FetchPlan</classname></ulink> object. The
<classname>FetchPlan</classname> maintains the set of active fetch groups and
the maximum fetch depth. It begins with the groups and depth defined in the
<ulink url="../apidocs/org/apache/openjpa/persistence/FetchPlan.html">
<classname>org.apache.openjpa.persistence.FetchPlan</classname></ulink> object.
The <classname>FetchPlan</classname> maintains the set of active fetch groups
and the maximum fetch depth. It begins with the groups and depth defined in the
<literal>openjpa.FetchGroups</literal> and <literal>openjpa.MaxFetchDepth
</literal> properties, but allows you to add or remove groups and change the
maximum fetch depth for an individual <classname>EntityManager</classname> or
<classname>Query</classname> through the methods below.
</para>
<programlisting>
public FetchPlan addFetchGroup (String group);
public FetchPlan addFetchGroups (String... groups);
public FetchPlan addFetchGroups (Collection groups);
public FetchPlan removeFetchGroup (String group);
public FetchPlan removeFetchGroups (String... groups);
public FetchPlan removeFetchGroups (Collection groups);
public FetchPlan resetFetchGroups ();
public Collection&lt;String&gt; getFetchGroups ();
public void clearFetchGroups ();
public FetchPlan addFetchGroup(String group);
public FetchPlan addFetchGroups(String... groups);
public FetchPlan addFetchGroups(Collection groups);
public FetchPlan removeFetchGrop(String group);
public FetchPlan removeFetchGroups(String... groups);
public FetchPlan removeFetchGroups(Collection groups);
public FetchPlan resetFetchGroups();
public Collection&lt;String&gt; getFetchGroups();
public void clearFetchGroups();
public FetchPlan setMaxFetchDepth(int depth);
public int getMaxFetchDepth();
</programlisting>
@ -1880,9 +1795,9 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAQuery kq = OpenJPAPersistence.cast (em.createQuery (...));
kq.getFetchPlan ().setMaxFetchDepth(3).addFetchGroup ("detail");
List results = kq.getResultList ();
OpenJPAQuery kq = OpenJPAPersistence.cast(em.createQuery(...));
kq.getFetchPlan().setMaxFetchDepth(3).addFetchGroup("detail");
List results = kq.getResultList();
</programlisting>
</example>
</section>
@ -1909,18 +1824,18 @@ fields that will be eagerly loaded from the database.
JPA <classname>FetchPlan</classname> methods:
</para>
<programlisting>
public FetchPlan addField (String field);
public FetchPlan addFields (String... fields);
public FetchPlan addFields (Class cls, String... fields);
public FetchPlan addFields (Collection fields);
public FetchPlan addFields (Class cls, Collection fields);
public FetchPlan removeField (String field);
public FetchPlan removeFields (String... fields);
public FetchPlan removeFields (Class cls, String... fields);
public FetchPlan removeFields (Collection fields);
public FetchPlan removeFields (Class cls, Collection fields);
public Collection&lt;String&gt; getFields ();
public void clearFields ();
public FetchPlan addField(String field);
public FetchPlan addFields(String... fields);
public FetchPlan addFields(Class cls, String... fields);
public FetchPlan addFields(Collection fields);
public FetchPlan addFields(Class cls, Collection fields);
public FetchPlan removeField(String field);
public FetchPlan removeFields(String... fields);
public FetchPlan removeFields(Class cls, String... fields);
public FetchPlan removeFields(Collection fields);
public FetchPlan removeFields(Class cls, Collection fields);
public Collection&lt;String&gt; getFields();
public void clearFields();
</programlisting>
<para>
The methods that take only string arguments use the fully-qualified field name,
@ -1952,9 +1867,9 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
kem.getFetchPlan ().addField (Magazine.class, "publisher");
Magazine mag = em.find (Magazine.class, magId);
OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
kem.getFetchPlan().addField(Magazine.class, "publisher");
Magazine mag = em.find(Magazine.class, magId);
</programlisting>
</example>
</section>
@ -2100,13 +2015,12 @@ but they can spawn recursive to-one joins.
<para>
Under the <literal>join</literal> subclass fetch mode, subclass data in joined
tables is selected by outer joining to all possible subclass tables of the type
being queried. Unjoined subclass data is selected with a SQL UNION where
possible. As you'll see below, subclass data fetching is configured separately
from relation fetching, and can be disabled for specific classes.
being queried. As you'll see below, subclass data fetching is configured
separately from relation fetching, and can be disabled for specific classes.
</para>
<note>
<para>
Some databases may not support UNIONs or outer joins. Also, OpenJPA can not use
Some databases may not support outer joins. Also, OpenJPA can not use
outer joins if you have set the <link linkend="openjpa.jdbc.DBDictionary">
<literal> DBDictionary</literal></link>'s <literal>JoinSyntax</literal> to
<literal>traditional</literal>. See <xref linkend="ref_guide_dbsetup_sql92"/>.
@ -2155,16 +2069,8 @@ relations to use parallel rather than join mode eager fetching using the
metadata extension described in <xref linkend="eager-fetch-mode"/>.
</para>
<para>
Setting your subclass fetch mode to <literal>parallel</literal> affects
table-per-class and vertical inheritance hierarchies. Under parallel mode,
OpenJPA issues separate selects for each subclass in a table-per-class
inheritance hierarchy, rather than UNIONing all subclass tables together as in
join mode. This applies to any operation on a table-per-class base class: query,
by-id lookup, or relation traversal.
</para>
<para>
When dealing with a vertically-mapped hierarchy, on the other hand, parallel
subclass fetch mode only applies to queries. Rather than outer-joining to
Parallel subclass fetch mode only applies to queries on joined inheritance
hierarchies. Rather than outer-joining to
subclass tables, OpenJPA will issue the query separately for each subclass. In
all other situations, parallel subclass fetch mode acts just like join mode in
regards to vertically-mapped subclasses.
@ -2253,12 +2159,12 @@ import org.apache.openjpa.persistence.jdbc.*;
...
Query q = em.createQuery ("select p from Person p where p.address.state = 'TX'");
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan ();
fetch.setEagerFetchMode (JDBCFetchPlan.EAGER_PARALLEL);
fetch.setSubclassFetchMode (JDBCFetchPlan.EAGER_JOIN);
List results = q.getResultList ();
Query q = em.createQuery("select p from Person p where p.address.state = 'TX'");
OpenJPAQuery kq = OpenJPAPersistence.cast(q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan();
fetch.setEagerFetchMode(JDBCFetchPlan.EAGER_PARALLEL);
fetch.setSubclassFetchMode(JDBCFetchPlan.EAGER_JOIN);
List results = q.getResultList();
</programlisting>
</example>
<para>
@ -2270,7 +2176,7 @@ subclass data fetching will take place, regardless of your metadata setting.
</para>
<para>
This applies to the eager fetch mode metadata extension as well (see
<xref linkend="eager-fetch-mode"/> ). You can use this extension to
<xref linkend="eager-fetch-mode"/>). You can use this extension to
disable eager fetching on a field or to declare that a collection would rather
use joins than parallel selects or vice versa. But an extension value of
<literal>join</literal> won't cause any eager joining if the fetch

View File

@ -73,7 +73,7 @@ In JPA, objects detach automatically when they are serialized or when a
<link linkend="jpa_overview_emfactory_perscontext">persistence context</link>
ends. The specification does not define any way to explicitly detach objects.
The extended
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>OpenJPAEntityManager</classname></ulink>, however, allows you to
explicitly detach objects at any time.
</para>
@ -111,8 +111,8 @@ your objects. Setting the <literal>RollbackOnly</literal> flag prevents OpenJPA
from flushing when detaching dirty objects; instead OpenJPA just runs its
pre-flush actions (see the <methodname>OpenJPAEntityManager.preFlush
</methodname>
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"> Javadoc
</ulink> for details).
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
Javadoc</ulink> for details).
</para>
<para>
This allows you to use the same instances in multiple
@ -152,7 +152,7 @@ attached instance's corresponding fields to null.
</listitem>
<listitem>
<para>
If the instance has <phrase> a <literal>Version</literal> field,</phrase>
If the instance has a <literal>Version</literal> field,
OpenJPA will consider the object detached if the version field has a non-default
value, and new otherwise.
</para>
@ -322,7 +322,7 @@ use detached state managers, as determined by the settings above.
<para>
You can also alter the set of fields that will be included in the detached graph
at runtime.
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>OpenJPAEntityManager</classname></ulink>s expose the following APIs
for controlling detached state:
</para>

View File

@ -3,7 +3,7 @@
Runtime Extensions
</title>
<para>
This chapter describes OpenJPA extensions to the standard <phrase>JPA</phrase>
This chapter describes OpenJPA extensions to the standard JPA
interfaces, and outlines some additional features of the OpenJPA runtime.
</para>
<section id="ref_guide_runtime_arch">
@ -17,7 +17,7 @@ and JDO are simply different "personalities" that can OpenJPA's native kernel
can adopt.
</para>
<para>
As a OpenJPA <phrase>JPA</phrase> user, you will not normally see beneath
As a OpenJPA user, you will not normally see beneath
OpenJPA's JPA personality. OpenJPA allows you to access its feature set without
leaving the comfort of JPA. Where OpenJPA goes beyond standard JPA
functionality, we have crafted JPA-specific APIs to each OpenJPA extension for
@ -190,7 +190,7 @@ features. The <classname>OpenJPAEntityManagerFactory</classname> offers APIs to
obtain managed and unmanaged <classname>EntityManager</classname>s from the
same factory, to access the OpenJPA data and query caches, and to perform other
OpenJPA-specific operations. See the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.html">
interface Javadoc</ulink> for details.
</para>
</section>
@ -216,7 +216,7 @@ interface Javadoc</ulink> for details.
</indexterm>
<para>
All OpenJPA <classname>EntityManager</classname>s implement the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>org.apache.openjpa.persistence.OpenJPAEntityManager</classname>
</ulink> interface. This interface extends the standard <classname>
javax.persistence.EntityManager</classname>. Just as the standard <classname>
@ -249,7 +249,7 @@ extensions this interface contains.
<para>
OpenJPA extends JPA's standard query functionality with the <classname>
org.apache.openjpa.persistence.OpenJPAQuery</classname> interface. See its
<ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc</ulink> for
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAQuery.html">Javadoc</ulink> for
details on the convenience methods it provides.
</para>
</section>
@ -276,7 +276,7 @@ details on the convenience methods it provides.
<para>
An <classname>Extent</classname> is a logical view of all persistent instances
of a given entity class, possibly including subclasses. OpenJPA adds the
<ulink url="../../api/openjpa/persistence/Extent.html"><classname>
<ulink url="../apidocs/org/apache/openjpa/persistence/Extent.html"><classname>
org.apache.openjpa.persistence.Extent</classname></ulink> class to the set of
Java Persistence APIs. The following code illustrates iterating over all
instances of the <classname>Magazine</classname> entity, without subclasses:
@ -310,8 +310,8 @@ for (Magazine m : mags)
In addition to the <classname>EntityManager</classname> object cache mandated by
the JPA specification, OpenJPA includes a flexible datastore-level cache. You
can access this cache from your JPA code using the
<ulink url="../../api/openjpa/persistence/StoreCache.html"><classname>
org.apache.openjpa.persistence.StoreCache</classname></ulink> facade.
<ulink url="../apidocs/org/apache/openjpa/persistence/StoreCache.html">
<classname>org.apache.openjpa.persistence.StoreCache</classname></ulink> facade.
<xref linkend="ref_guide_cache"/> has detailed information on OpenJPA's
data caching system, including the <classname>StoreCache</classname> facade.
</para>
@ -327,9 +327,9 @@ data caching system, including the <classname>StoreCache</classname> facade.
</indexterm>
<para>
OpenJPA can cache query results as well as persistent object data. The
<ulink url="../../api/openjpa/persistence/QueryResultCache.html"><classname>
org.apache.openjpa.persistence.QueryResultCache</classname></ulink> is an
JPA-flavored facade to OpenJPA's internal query cache. See
<ulink url="../apidocs/org/apache/openjpa/persistence/QueryResultCache.html">
<classname>org.apache.openjpa.persistence.QueryResultCache</classname></ulink>
is an JPA-flavored facade to OpenJPA's internal query cache. See
<xref linkend="ref_guide_cache_query"/> for details on query caching in
OpenJPA.
</para>
@ -361,10 +361,10 @@ groups</link>, and <link linkend="ref_guide_locking">lock levels</link>.
</para>
<para>
OpenJPA goes one step further, extending <classname>FetchPlan</classname> with
<ulink url="../../api/openjpa/persistence/jdbc/JDBCFetchPlan.html"><classname>
org.apache.openjpa.persistence.jdbc.JDBCFetchPlan</classname></ulink> to add
additional JDBC-specific tuning methods. Unless you have customized OpenJPA to
use a non-relational back-end (see
<ulink url="../apidocs/org/apache/openjpa/persistence/jdbc/JDBCFetchPlan.html">
<classname>org.apache.openjpa.persistence.jdbc.JDBCFetchPlan</classname></ulink>
to add additional JDBC-specific tuning methods. Unless you have customized
OpenJPA to use a non-relational back-end (see
<xref linkend="ref_guide_enterprise_abstractstore"/> ), all <classname>
FetchPlan</classname>s in OpenJPA implement <classname>JDBCFetchPlan</classname>
, so feel free to cast to this interface.
@ -397,10 +397,10 @@ FetchPlan</classname> s.
</primary>
</indexterm>
<para>
<ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html"><classname>
org.apache.openjpa.persistence.OpenJPAPersistence</classname></ulink> is a
static helper class that adds OpenJPA-specific utility methods to <classname>
javax.persistence.Persistence</classname>.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAPersistence.html">
<classname>org.apache.openjpa.persistence.OpenJPAPersistence</classname></ulink>
is a static helper class that adds OpenJPA-specific utility methods to
<classname>javax.persistence.Persistence</classname>.
</para>
</section>
</section>
@ -586,7 +586,7 @@ In addition to the standard
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html">
<methodname>EntityManager.lock (Object, LockModeType)</methodname></ulink>
method, the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>OpenJPAEntityManager</classname></ulink> exposes the following
methods to lock objects explicitly:
</para>
@ -879,9 +879,9 @@ changes. This chapter describes how to use and configure OpenJPA savepoints.
Using Savepoints
</title>
<para>
OpenJPA's <phrase>
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
<classname>OpenJPAEntityManager</classname></ulink></phrase> have the following
OpenJPA's
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
<classname>OpenJPAEntityManager</classname></ulink> have the following
methods to control savepoint behavior. Note that the savepoints work in tandem
with the current transaction. This means that savepoints require an open
transaction, and that a rollback of the transaction will rollback all of the
@ -958,7 +958,8 @@ kem.getTransaction ().commit ();
Configuring Savepoints
</title>
<para>
OpenJPA uses the <ulink url="javadoc/openjpa/kernel/SavepointManager">
OpenJPA uses the
<ulink url="../apidocs/org/apache/openjpa/kernel/SavepointManager">
<classname>org.apache.openjpa.kernel.SavepointManager</classname></ulink>
<link linkend="ref_guide_conf_plugins">plugin</link> to handle perserving the
savepoint state. OpenJPA includes the following <classname>SavepointManager
@ -1199,8 +1200,8 @@ registration for very specific extensions that do not apply globally.
</para>
<para>
See the <classname>OpenJPAQuery</classname>
<ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc</ulink> for
details.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAQuery.html">
Javadoc</ulink> for details.
</para>
</listitem>
</itemizedlist>
@ -1267,8 +1268,8 @@ registration for very specific aggregates that do not apply globally.
</para>
<para>
See the <classname>OpenJPAQuery</classname>
<ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc</ulink> for
details.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAQuery.html">
Javadoc</ulink> for details.
</para>
</listitem>
</itemizedlist>
@ -1687,7 +1688,8 @@ OpenJPA allows you to access named generators at runtime through the
public Generator getNamedGenerator (String name);
</programlisting>
<para>
The returned <ulink url="../../api/openjpa/persistence/Generator.html">
The returned
<ulink url="../apidocs/org/apache/openjpa/persistence/Generator.html">
<classname>org.apache.openjpa.persistence.Generator</classname></ulink> is a
facade over an internal OpenJPA <classname>Seq</classname>.
</para>
@ -1697,8 +1699,8 @@ retrieve the identity generator of any class, or the generator of any field.
With these APIs, you do not have to know the generator name. Additionally, they
allow you to access the implicit generator used by default for datastore
identity classes. See the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"> Javadoc
</ulink> for the <methodname> OpenJPAEntityManager.getIdentityGenerator
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
Javadoc</ulink> for the <methodname> OpenJPAEntityManager.getIdentityGenerator
</methodname> and <methodname>OpenJPAEntityManager.getFieldGenerator
</methodname> methods for API details.
</para>

View File

@ -4,7 +4,7 @@
</title>
<para>
Following is a table of the database and JDBC driver versions that are supported
by OpenJPA <phrase>JPA</phrase>.
by OpenJPA.
</para>
<table tocentry="1">
<title>
@ -326,10 +326,7 @@ datastore transactions cannot use the pessimistic lock manager.
<listitem>
<para>
Interbase does not support the <literal>LOWER</literal>, <literal>SUBSTRING
</literal>, or <literal>INSTR</literal> SQL functions, which means that
<methodname>toLowerCase()</methodname>, <methodname>indexOf()</methodname>, and
<methodname>substring()</methodname> methods in <phrase>JPA</phrase> QL cannot
be used.
</literal>, or <literal>INSTR</literal> SQL functions>
</para>
</listitem>
</itemizedlist>
@ -482,10 +479,7 @@ Firebird does not support auto-increment columns.
<listitem>
<para>
Firebird does not support the <literal>LOWER</literal>, <literal>SUBSTRING
</literal>, or <literal>INSTR</literal> SQL functions, which means that
<methodname>toLowerCase()</methodname>, <methodname>indexOf()</methodname>, and
<methodname>substring()</methodname> methods in <phrase>JPA</phrase> QL cannot
be used.
</literal>, or <literal>INSTR</literal> SQL functions.
</para>
</listitem>
</itemizedlist>