Search in sources :

Example 36 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class OneToManyMapping method extractKeyFromTargetRow.

/**
 * INTERNAL:
 * Extract the source primary key value from the target row.
 * Used for batch reading, most following same order and fields as in the mapping.
 */
@Override
protected Object extractKeyFromTargetRow(AbstractRecord row, AbstractSession session) {
    int size = this.sourceKeyFields.size();
    Object[] key = new Object[size];
    ConversionManager conversionManager = session.getDatasourcePlatform().getConversionManager();
    for (int index = 0; index < size; index++) {
        DatabaseField targetField = this.targetForeignKeyFields.get(index);
        DatabaseField sourceField = this.sourceKeyFields.get(index);
        Object value = row.get(targetField);
        // Must ensure the classification gets a cache hit.
        try {
            value = conversionManager.convertObject(value, sourceField.getType());
        } catch (ConversionException e) {
            throw ConversionException.couldNotBeConverted(this, getDescriptor(), e);
        }
        key[index] = value;
    }
    return new CacheId(key);
}
Also used : ConversionException(org.eclipse.persistence.exceptions.ConversionException) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) ConversionManager(org.eclipse.persistence.internal.helper.ConversionManager)

Example 37 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class OracleChangeNotificationListener method initialize.

/**
 * Initialize the descriptor to receive database change events.
 * This is called when the descriptor is initialized.
 */
@Override
public void initialize(final ClassDescriptor descriptor, AbstractSession session) {
    if (descriptor.getOptimisticLockingPolicy() == null) {
        boolean requiresLocking = descriptor.hasMultipleTables();
        for (DatabaseMapping mapping : descriptor.getMappings()) {
            if (mapping.isCollectionMapping()) {
                requiresLocking = true;
            }
        }
        if (requiresLocking) {
            session.log(SessionLog.WARNING, SessionLog.METADATA, "locking_required_for_database_change_notification", descriptor.getJavaClass());
        }
    }
    final DatabaseField rowId = descriptor.buildField(new DatabaseField(ROWID));
    final List<DatabaseField> fields = new ArrayList<DatabaseField>();
    fields.add(rowId);
    // May already have the index if has inheritance.
    CacheIndex existingIndex = descriptor.getCachePolicy().getCacheIndex(fields);
    if (existingIndex == null) {
        if (descriptor.isChildDescriptor()) {
            existingIndex = descriptor.getInheritancePolicy().getRootParentDescriptor().getCachePolicy().getCacheIndex(fields);
        }
        if (existingIndex == null) {
            existingIndex = new CacheIndex(fields);
            existingIndex.setIsUpdateable(false);
            existingIndex.setIsInsertable(false);
        }
        descriptor.getCachePolicy().addCacheIndex(existingIndex);
    }
    final CacheIndex index = existingIndex;
    rowId.setInsertable(false);
    rowId.setUpdatable(false);
    rowId.setCreatable(false);
    descriptor.getFields().add(rowId);
    descriptor.getAllFields().add(rowId);
    final ValueReadQuery rowIdQuery = new ValueReadQuery();
    rowIdQuery.setName(ROWID);
    SQLSelectStatement sqlStatement = new SQLSelectStatement();
    sqlStatement.setWhereClause(descriptor.getObjectBuilder().getPrimaryKeyExpression());
    sqlStatement.addField(rowId);
    sqlStatement.addTable(descriptor.getTables().get(0));
    rowIdQuery.setSQLStatement(sqlStatement);
    sqlStatement.normalize(session, null);
    descriptor.getEventManager().addListener(new DescriptorEventAdapter() {

        @Override
        public void postMerge(DescriptorEvent event) {
            if ((event.getChangeSet() != null) && event.getChangeSet().hasChanges()) {
                Object id = event.getChangeSet().getId();
                CacheKey cacheKey = event.getChangeSet().getActiveCacheKey();
                if (cacheKey == null) {
                    cacheKey = event.getSession().getParent().getIdentityMapAccessorInstance().getIdentityMapManager().getCacheKeyForObject(id, descriptor.getJavaClass(), descriptor, false);
                }
                cacheKey.setTransactionId(event.getSession().getProperty(ORA_TRANSACTION_ID));
                if (event.getChangeSet().isNew()) {
                    AbstractRecord row = descriptor.getObjectBuilder().buildRowFromPrimaryKeyValues(id, event.getSession());
                    Object rowid = event.getSession().executeQuery(rowIdQuery, row);
                    CacheId indexValue = new CacheId(new Object[] { rowid });
                    event.getSession().getParent().getIdentityMapAccessorInstance().getIdentityMapManager().putCacheKeyByIndex(index, indexValue, cacheKey, descriptor);
                }
            }
        }

        @Override
        public void postUpdate(DescriptorEvent event) {
            Object txId = event.getSession().getProperty(ORA_TRANSACTION_ID);
            if (txId == null) {
                txId = event.getSession().executeQuery(transactionIdQuery);
                event.getSession().setProperty(ORA_TRANSACTION_ID, txId);
            }
        }
    });
}
Also used : CacheIndex(org.eclipse.persistence.descriptors.CacheIndex) ValueReadQuery(org.eclipse.persistence.queries.ValueReadQuery) ArrayList(java.util.ArrayList) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) DescriptorEvent(org.eclipse.persistence.descriptors.DescriptorEvent) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) DescriptorEventAdapter(org.eclipse.persistence.descriptors.DescriptorEventAdapter) SQLSelectStatement(org.eclipse.persistence.internal.expressions.SQLSelectStatement) CacheKey(org.eclipse.persistence.internal.identitymaps.CacheKey)

Example 38 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class EntityManagerImpl method findInternal.

/**
 * Find by primary key.
 *
 * @param descriptor
 *            - the entity class to find.
 * @param id
 *            - the entity primary key value, or primary key class, or a
 *            List of primary key values.
 * @return the found entity instance or null, if the entity does not exist.
 * @throws IllegalArgumentException
 *             if the first argument does not denote an entity type or the
 *             second argument is not a valid type for that entity's primary
 *             key.
 */
protected Object findInternal(ClassDescriptor descriptor, AbstractSession session, Object id, LockModeType lockMode, Map<String, Object> properties) {
    if (id == null) {
        // gf721 - check for null PK
        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("null_pk"));
    }
    Object primaryKey;
    if (id instanceof List) {
        if (descriptor.getCacheKeyType() == CacheKeyType.ID_VALUE) {
            if (((List) id).isEmpty()) {
                primaryKey = null;
            } else {
                primaryKey = ((List) id).get(0);
            }
        } else {
            primaryKey = new CacheId(((List) id).toArray());
        }
    } else if (id instanceof CacheId) {
        primaryKey = id;
    } else {
        CMPPolicy policy = descriptor.getCMPPolicy();
        Class<Object> pkClass = policy.getPKClass();
        if ((pkClass != null) && (pkClass != id.getClass()) && (!BasicTypeHelperImpl.getInstance().isStrictlyAssignableFrom(pkClass, id.getClass()))) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("invalid_pk_class", new Object[] { descriptor.getCMPPolicy().getPKClass(), id.getClass() }));
        }
        primaryKey = policy.createPrimaryKeyFromId(id, session);
    }
    // Must avoid using the new JPA 2.0 Enum values directly to allow JPA 1.0 jars to still work.
    if (lockMode != null && (lockMode.name().equals(ObjectLevelReadQuery.PESSIMISTIC_READ) || lockMode.name().equals(ObjectLevelReadQuery.PESSIMISTIC_WRITE) || lockMode.name().equals(ObjectLevelReadQuery.PESSIMISTIC_FORCE_INCREMENT))) {
        // PERF: check if the UnitOfWork has pessimistically locked objects to avoid a cache query
        if (session.isUnitOfWork() && ((UnitOfWorkImpl) session).hasPessimisticLockedObjects()) {
            ReadObjectQuery query = new ReadObjectQuery();
            query.setReferenceClass(descriptor.getJavaClass());
            query.setSelectionId(primaryKey);
            query.checkCacheOnly();
            Object cachedEntity = session.executeQuery(query);
            if (cachedEntity != null && ((UnitOfWorkImpl) session).isPessimisticLocked(cachedEntity)) {
                return cachedEntity;
            }
        }
    }
    // Get the read object query and apply the properties to it.
    // PERF: use descriptor defined query to avoid extra query creation.
    ReadObjectQuery query = descriptor.getQueryManager().getReadObjectQuery();
    if (query == null) {
        // The properties/query hints and setIsExecutionClone etc. is set
        // in the getReadObjectQuery.
        query = getReadObjectQuery(descriptor.getJavaClass(), primaryKey, properties);
    } else {
        query.checkPrepare(session, null);
        query = (ReadObjectQuery) query.clone();
        // Apply the properties if there are some.
        QueryHintsHandler.apply(properties, query, session.getLoader(), session);
        query.setIsExecutionClone(true);
        query.setSelectionId(primaryKey);
    }
    // the properties.
    if (properties == null || (!properties.containsKey(QueryHints.CACHE_USAGE) && !properties.containsKey(QueryHints.CACHE_RETRIEVE_MODE) && !properties.containsKey(QueryHints.CACHE_STORE_MODE) && !properties.containsKey("jakarta.persistence.cacheRetrieveMode") && !properties.containsKey("jakarta.persistence.cacheStoreMode"))) {
        query.conformResultsInUnitOfWork();
    }
    return executeQuery(query, lockMode, session);
}
Also used : CMPPolicy(org.eclipse.persistence.descriptors.CMPPolicy) ReadObjectQuery(org.eclipse.persistence.queries.ReadObjectQuery) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

CacheId (org.eclipse.persistence.internal.identitymaps.CacheId)38 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)19 ArrayList (java.util.ArrayList)12 List (java.util.List)10 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)8 ConversionException (org.eclipse.persistence.exceptions.ConversionException)8 ConversionManager (org.eclipse.persistence.internal.helper.ConversionManager)8 CacheKey (org.eclipse.persistence.internal.identitymaps.CacheKey)5 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)5 HashMap (java.util.HashMap)4 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)4 XMLField (org.eclipse.persistence.oxm.XMLField)4 Vector (java.util.Vector)3 CacheKeyType (org.eclipse.persistence.annotations.CacheKeyType)3 CoreDescriptor (org.eclipse.persistence.core.descriptors.CoreDescriptor)3 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)3 Descriptor (org.eclipse.persistence.internal.oxm.mappings.Descriptor)3 ReadAllQuery (org.eclipse.persistence.queries.ReadAllQuery)3 SAXException (org.xml.sax.SAXException)3 SAXParseException (org.xml.sax.SAXParseException)3