blob: 084174c75dd097991f2bbc484d72f7b7acb4fb78 [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// James Sutherland (Oracle) - initial API and implementation
package org.eclipse.persistence.descriptors.partitioning;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.server.ClientSession;
/**
* PUBLIC:
* FieldPartitioningPolicy partitions access to a database cluster by a field value from the object,
* such as the object's id, location, or tenant.
* All write or read request for object's with that value are sent to the server.
* If a query does not include the field as a parameter, then it can either be sent
* to all server's and unioned, or left to the sesion's default behavior.
* @author James Sutherland
* @since EclipseLink 2.2
*/
public abstract class FieldPartitioningPolicy extends PartitioningPolicy {
/** The column to partition by. */
protected DatabaseField partitionField;
/** If query does not have the partition field in it, should the query be sent to all databases. */
protected boolean unionUnpartitionableQueries = false;
protected FieldPartitioningPolicy() {
super();
}
protected FieldPartitioningPolicy(String partitionField) {
super();
this.partitionField = new DatabaseField(partitionField);
}
protected FieldPartitioningPolicy(String partitionField, boolean unionUnpartitionableQueries) {
this(partitionField);
this.unionUnpartitionableQueries = unionUnpartitionableQueries;
}
/**
* PUBLIC:
* Return the database column or query parameter to partition queries by.
* This is the table column name, not the class attribute name.
* The column value must be included in the query and should normally be part of the object's Id.
* This can also be the name of a query parameter.
* If a query does not contain the field the query will not be partitioned.
*/
public DatabaseField getPartitionField() {
return partitionField;
}
/**
* PUBLIC:
* Set the database column or query parameter to partition queries by.
* This is the table column name, not the class attribute name.
* The column value must be included in the query and should normally be part of the object's Id.
* This can also be the name of a query parameter.
* If a query does not contain the field the query will not be partitioned.
*/
public void setPartitionField(DatabaseField partitionField) {
this.partitionField = partitionField;
}
/**
* PUBLIC:
* Return the database column or query parameter to partition queries by.
* This is the table column name, not the class attribute name.
* The column value must be included in the query and should normally be part of the object's Id.
* This can also be the name of a query parameter.
* If a query does not contain the field the query will not be partitioned.
*/
public String getPartitionFieldName() {
return getPartitionField().getName();
}
/**
* PUBLIC:
* Set the database column or query parameter to partition queries by.
* This is the table column name, not the class attribute name.
* The column value must be included in the query and should normally be part of the object's Id.
* This can also be the name of a query parameter.
* If a query does not contain the field the query will not be partitioned.
*/
public void setPartitionField(String partitionField) {
this.partitionField = new DatabaseField(partitionField);
}
/**
* PUBLIC:
* Return if queries that do not contain the partition field should be sent
* to every database and have the result unioned.
*/
public boolean getUnionUnpartitionableQueries() {
return unionUnpartitionableQueries;
}
/**
* PUBLIC:
* Set if queries that do not contain the partition field should be sent
* to every database and have the result unioned.
*/
public void setUnionUnpartitionableQueries(boolean unionUnpartitionableQueries) {
this.unionUnpartitionableQueries = unionUnpartitionableQueries;
}
/**
* INTERNAL:
* If persist should be partitioned, extra value from object.
*/
protected Object extractPartitionValueForPersist(AbstractSession session, Object object, ClassDescriptor descriptor) {
if (!session.isClientSession()) {
return null;
}
ClientSession client = (ClientSession)session;
// Only assign the connection if exclusive.
if (!client.isExclusiveIsolatedClientSession() || client.hasWriteConnection()) {
return null;
}
return descriptor.getObjectBuilder().extractValueFromObjectForField(object, this.partitionField, session);
}
}