mirror of https://github.com/apache/openjpa.git
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:
parent
e30632b60b
commit
bdae6535ec
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}".
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 > 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 > 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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 <T> T find (Class<T> cls, Object oid);
|
||||
public <T> T find(Class<T> 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 <T> T getReference (Class<T> cls, Object oid);
|
||||
public <T> T getReference(Class<T> 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
|
||||
|
|
|
@ -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.<property></literal>, where <emphasis><property>
|
||||
</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 && mag3 != mag2);
|
||||
Magazine mag4 = em.find (Magazine.class (magId);
|
||||
assertTrue (mag4 == mag3);
|
||||
Magazine mag3 = em.find(Magazine.class, magId);
|
||||
assertTrue(mag3 != mag1 && 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
|
@ -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) { ... }
|
||||
|
||||
...
|
||||
}
|
||||
|
|
|
@ -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 && isbn.equals (mi.isbn)))
|
||||
|| (isbn != null && isbn.equals(mi.isbn)))
|
||||
&& (title == mi.title
|
||||
|| (title != null && title.equals (mi.title)));
|
||||
|| (title != null && 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<Photo> photos;
|
||||
|
||||
@PostLoad
|
||||
public void convertPhotos ()
|
||||
{
|
||||
data = new byte[photos.size ()][];
|
||||
for (int i = 0; i < photos.size (); i++)
|
||||
data[i] = photos.get (i).toByteArray ();
|
||||
public void convertPhotos() {
|
||||
data = new byte[photos.size()][];
|
||||
for (int i = 0; i < 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>
|
||||
|
|
|
@ -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
|
@ -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 > 5 AND PRICE < 10", Magazine.class);
|
||||
List<Magazine> results = query.getResultList ();
|
||||
List<Magazine> results = (List<Magazine>) 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 > ?1 AND PRICE < ?2", Magazine.class);
|
||||
|
||||
query.setParameter (1, 5d);
|
||||
query.setParameter (2, 10d);
|
||||
query.setParameter(1, 5d);
|
||||
query.setParameter(2, 10d);
|
||||
|
||||
List<Magazine> results = query.getResultList ();
|
||||
List<Magazine> results = (List<Magazine>) query.getResultList();
|
||||
for (Magazine mag : results)
|
||||
processMagazine (mag);
|
||||
</programlisting>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
<property name="openjpa.Log" value="SQL=TRACE"/>
|
||||
<property name="openjpa.ConnectionFactoryProperties"
|
||||
value="MaxActive=100, PrettyPrint=true, PrettyPrintLineLength=72"/>
|
||||
value="PrettyPrint=true, PrettyPrintLineLength=72"/>
|
||||
</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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
<property name="openjpa.MetaDataFactory" value="jpa"/>
|
||||
<property name="openjpa.MetaDataFactory" value="jpa(ClasspathScan=build;lib.jar)"/>
|
||||
</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|<field name>[ 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<String> subtitles;
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 <true/t | false/f></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>
|
||||
<class name="Magazine">
|
||||
<field name="coverPhoto"/>
|
||||
...
|
||||
</class>
|
||||
<class name="Photograph">
|
||||
<field name="mag">
|
||||
<extension vendor-name="openjpa" key="inverse-logical" value="coverPhoto"/>
|
||||
</field>
|
||||
...
|
||||
</class>
|
||||
</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<Employee> 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<String> 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<String> 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<String> 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<String> 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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue