io.ebeaninternal.server.deploy.BeanProperty Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ebean Show documentation
Show all versions of ebean Show documentation
composite of common runtime dependencies for all platforms
package io.ebeaninternal.server.deploy;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.ValuePair;
import io.ebean.bean.EntityBean;
import io.ebean.bean.PersistenceContext;
import io.ebean.config.EncryptKey;
import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.plugin.Property;
import io.ebean.text.StringParser;
import io.ebean.util.SplitName;
import io.ebean.util.StringHelper;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonReader;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenCreated;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenModified;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import io.ebeaninternal.server.el.ElPropertyChainBuilder;
import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.properties.BeanPropertyGetter;
import io.ebeaninternal.server.properties.BeanPropertySetter;
import io.ebeaninternal.server.query.STreeProperty;
import io.ebeaninternal.server.query.SqlBeanLoad;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.type.DataBind;
import io.ebeaninternal.server.type.LocalEncryptedType;
import io.ebeaninternal.server.type.ScalarType;
import io.ebeaninternal.server.type.ScalarTypeBoolean;
import io.ebeaninternal.server.type.ScalarTypeEnum;
import io.ebeaninternal.server.type.ScalarTypeLogicalType;
import io.ebeaninternal.util.ValueUtil;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
import io.ebeanservice.docstore.api.support.DocStructure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Description of a property of a bean. Includes its deployment information such
* as database column mapping information.
*/
public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
private static final Logger logger = LoggerFactory.getLogger(BeanProperty.class);
/**
* Flag to mark this is the id property.
*/
final boolean id;
final boolean importedPrimaryKey;
/**
* Flag to make this as a dummy property for unidirecitonal relationships.
*/
final boolean unidirectionalShadow;
/**
* Flag set if this maps to the inheritance discriminator column
*/
final boolean discriminator;
/**
* Flag to mark the property as embedded. This could be on
* BeanPropertyAssocOne rather than here. Put it here for checking Id type
* (embedded or not).
*/
final boolean embedded;
/**
* Flag indicating if this the version property.
*/
final boolean version;
final boolean naturalKey;
/**
* Set if this property is nullable.
*/
final boolean nullable;
final boolean unique;
/**
* Is this property include in database resultSet.
*/
final boolean dbRead;
/**
* Include in DB insert.
*/
final boolean dbInsertable;
/**
* Include in DB update.
*/
final boolean dbUpdatable;
/**
* True if the property is based on a SECONDARY table.
*/
final boolean secondaryTable;
final TableJoin secondaryTableJoin;
final String secondaryTableJoinPrefix;
/**
* The property is inherited from a super class.
*/
final boolean inherited;
final Class> owningType;
final boolean local;
/**
* True if the property is a Clob, Blob LongVarchar or LongVarbinary.
*/
final boolean lob;
final boolean fetchEager;
final boolean isTransient;
/**
* The logical bean property name.
*/
final String name;
final int propertyIndex;
/**
* The reflected field.
*/
final Field field;
/**
* The bean type.
*/
final Class> propertyType;
final String dbBind;
/**
* The database column. This can include quoted identifiers.
*/
final String dbColumn;
final String elPrefix;
final String elPlaceHolder;
final String elPlaceHolderEncrypted;
/**
* Select part of a SQL Formula used to populate this property.
*/
final String sqlFormulaSelect;
/**
* Join part of a SQL Formula.
*/
final String sqlFormulaJoin;
final String aggregation;
final boolean formula;
/**
* Set to true if stored encrypted.
*/
final boolean dbEncrypted;
final boolean localEncrypted;
final int dbEncryptedType;
/**
* The jdbc data type this maps to.
*/
final int dbType;
final boolean excludedFromHistory;
/**
* Generator for insert or update timestamp etc.
*/
final GeneratedProperty generatedProperty;
final BeanPropertyGetter getter;
final BeanPropertySetter setter;
final BeanDescriptor> descriptor;
/**
* Used for non-jdbc native types (java.util.Date Enums etc). Converts from
* logical to jdbc types.
*/
@SuppressWarnings("rawtypes")
final ScalarType scalarType;
final DocPropertyOptions docOptions;
/**
* The length or precision for DB column.
*/
final int dbLength;
/**
* The scale for DB column (decimal).
*/
final int dbScale;
/**
* Deployment defined DB column definition.
*/
final String dbColumnDefn;
/**
* DB Column default value for DDL definition (FALSE, NOW etc).
*/
final String dbColumnDefault;
final List dbMigrationInfos;
/**
* Database DDL column comment.
*/
final String dbComment;
final DbEncryptFunction dbEncryptFunction;
int deployOrder;
final boolean jsonSerialize;
final boolean jsonDeserialize;
final boolean unmappedJson;
final boolean tenantId;
final boolean draft;
final boolean draftOnly;
final boolean draftDirty;
final boolean draftReset;
final boolean softDelete;
final String softDeleteDbSet;
final String softDeleteDbPredicate;
public BeanProperty(DeployBeanProperty deploy) {
this(null, deploy);
}
public BeanProperty(BeanDescriptor> descriptor, DeployBeanProperty deploy) {
this.descriptor = descriptor;
this.name = InternString.intern(deploy.getName());
this.propertyIndex = deploy.getPropertyIndex();
this.unidirectionalShadow = deploy.isUndirectionalShadow();
this.importedPrimaryKey = deploy.isImportedPrimaryKey();
this.discriminator = deploy.isDiscriminator();
this.localEncrypted = deploy.isLocalEncrypted();
this.dbEncrypted = deploy.isDbEncrypted();
this.dbEncryptedType = deploy.getDbEncryptedType();
this.dbEncryptFunction = deploy.getDbEncryptFunction();
this.dbBind = deploy.getDbBind();
this.dbRead = deploy.isDbRead();
this.dbInsertable = deploy.isDbInsertable();
this.dbUpdatable = deploy.isDbUpdateable();
this.excludedFromHistory = deploy.isExcludedFromHistory();
this.unmappedJson = deploy.isUnmappedJson();
this.tenantId = deploy.isTenantId();
this.draft = deploy.isDraft();
this.draftDirty = deploy.isDraftDirty();
this.draftOnly = deploy.isDraftOnly();
this.draftReset = deploy.isDraftReset();
this.secondaryTable = deploy.isSecondaryTable();
if (secondaryTable) {
this.secondaryTableJoin = new TableJoin(deploy.getSecondaryTableJoin());
this.secondaryTableJoinPrefix = deploy.getSecondaryTableJoinPrefix();
} else {
this.secondaryTableJoin = null;
this.secondaryTableJoinPrefix = null;
}
this.fetchEager = deploy.isFetchEager();
this.isTransient = deploy.isTransient();
this.nullable = deploy.isNullable();
this.unique = deploy.isUnique();
this.naturalKey = deploy.isNaturalKey();
this.dbLength = deploy.getDbLength();
this.dbScale = deploy.getDbScale();
this.dbColumnDefn = InternString.intern(deploy.getDbColumnDefn());
this.dbColumnDefault = deploy.getDbColumnDefaultSqlLiteral();
this.dbMigrationInfos = deploy.getDbMigrationInfos();
this.inherited = false;// deploy.isInherited();
this.owningType = deploy.getOwningType();
this.local = deploy.isLocal();
this.version = deploy.isVersionColumn();
this.embedded = deploy.isEmbedded();
this.id = deploy.isId();
this.generatedProperty = deploy.getGeneratedProperty();
this.getter = deploy.getGetter();
this.setter = deploy.getSetter();
this.dbColumn = tableAliasIntern(descriptor, deploy.getDbColumn(), false, null);
this.dbComment = deploy.getDbComment();
this.aggregation = deploy.parseAggregation();
this.sqlFormulaJoin = InternString.intern(deploy.getSqlFormulaJoin());
this.sqlFormulaSelect = InternString.intern(deploy.getSqlFormulaSelect());
this.formula = sqlFormulaSelect != null;
this.dbType = deploy.getDbType();
this.scalarType = deploy.getScalarType();
this.lob = isLobType(dbType);
this.propertyType = deploy.getPropertyType();
this.field = deploy.getField();
this.docOptions = deploy.getDocPropertyOptions();
this.elPlaceHolder = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), false, null);
this.elPlaceHolderEncrypted = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), dbEncrypted, dbColumn);
this.elPrefix = deploy.getElPrefix();
this.softDelete = deploy.isSoftDelete();
if (softDelete) {
ScalarTypeBoolean.BooleanBase boolType = (ScalarTypeBoolean.BooleanBase) scalarType;
this.softDeleteDbSet = dbColumn + "=" + boolType.getDbTrueLiteral();
this.softDeleteDbPredicate = "." + dbColumn + " = " + boolType.getDbFalseLiteral();
} else {
this.softDeleteDbSet = null;
this.softDeleteDbPredicate = null;
}
this.jsonSerialize = deploy.isJsonSerialize();
this.jsonDeserialize = deploy.isJsonDeserialize();
}
private String tableAliasIntern(BeanDescriptor> descriptor, String s, boolean dbEncrypted, String dbColumn) {
if (descriptor != null) {
s = StringHelper.replaceString(s, "${ta}.", "${}");
s = StringHelper.replaceString(s, "${ta}", "${}");
if (dbEncrypted) {
s = dbEncryptFunction.getDecryptSql(s);
String namedParam = ":encryptkey_" + descriptor.getBaseTable() + "___" + dbColumn;
s = StringHelper.replaceString(s, "?", namedParam);
}
}
return InternString.intern(s);
}
/**
* Create a Matching BeanProperty with some attributes overridden.
*
* Primarily for supporting Embedded beans with overridden dbColumn
* mappings.
*
*/
public BeanProperty(BeanProperty source, BeanPropertyOverride override) {
this.descriptor = source.descriptor;
this.name = InternString.intern(source.getName());
this.propertyIndex = source.propertyIndex;
this.dbColumn = InternString.intern(override.getDbColumn());
// override with sqlFormula not currently supported
this.sqlFormulaJoin = null;
this.sqlFormulaSelect = null;
this.formula = false;
this.aggregation = null;
this.excludedFromHistory = source.excludedFromHistory;
this.tenantId = source.tenantId;
this.draft = source.draft;
this.draftDirty = source.draftDirty;
this.draftOnly = source.draftOnly;
this.draftReset = source.draftReset;
this.softDelete = source.softDelete;
this.softDeleteDbSet = source.softDeleteDbSet;
this.softDeleteDbPredicate = source.softDeleteDbPredicate;
this.fetchEager = source.fetchEager;
this.importedPrimaryKey = source.importedPrimaryKey;
this.unidirectionalShadow = source.unidirectionalShadow;
this.discriminator = source.discriminator;
this.localEncrypted = source.isLocalEncrypted();
this.isTransient = source.isTransient();
this.secondaryTable = source.isSecondaryTable();
this.secondaryTableJoin = source.secondaryTableJoin;
this.secondaryTableJoinPrefix = source.secondaryTableJoinPrefix;
this.dbComment = source.dbComment;
this.dbBind = source.getDbBind();
this.dbEncrypted = source.isDbEncrypted();
this.dbEncryptedType = source.getDbEncryptedType();
this.dbEncryptFunction = source.dbEncryptFunction;
this.dbRead = source.isDbRead();
this.dbInsertable = source.isDbInsertable();
this.dbUpdatable = source.isDbUpdatable();
this.nullable = source.isNullable();
this.unique = source.isUnique();
this.naturalKey = source.isNaturalKey();
this.dbLength = source.getDbLength();
this.dbScale = source.getDbScale();
this.dbColumnDefn = InternString.intern(source.getDbColumnDefn());
this.dbColumnDefault = source.dbColumnDefault;
this.dbMigrationInfos = source.dbMigrationInfos;
this.inherited = source.isInherited();
this.owningType = source.owningType;
this.local = owningType.equals(descriptor.getBeanType());
this.version = source.isVersion();
this.embedded = source.isEmbedded();
this.id = source.isId();
this.generatedProperty = source.getGeneratedProperty();
this.getter = source.getter;
this.setter = source.setter;
this.dbType = source.getDbType(true);
this.scalarType = source.scalarType;
this.lob = isLobType(dbType);
this.propertyType = source.getPropertyType();
this.field = source.getField();
this.docOptions = source.docOptions;
this.unmappedJson = source.unmappedJson;
this.elPrefix = override.replace(source.elPrefix, source.dbColumn);
this.elPlaceHolder = override.replace(source.elPlaceHolder, source.dbColumn);
this.elPlaceHolderEncrypted = override.replace(source.elPlaceHolderEncrypted, source.dbColumn);
this.jsonSerialize = source.jsonSerialize;
this.jsonDeserialize = source.jsonDeserialize;
}
/**
* Initialise the property before returning to client code. Used to
* initialise variables that can't be done in construction due to recursive
* issues.
*/
public void initialise(BeanDescriptorInitContext initContext) {
// do nothing for normal BeanProperty
if (!isTransient && scalarType == null) {
throw new RuntimeException("No ScalarType assigned to " + descriptor.getFullName() + "." + getName());
}
}
/**
* Return the order this property appears in the bean.
*/
public int getDeployOrder() {
return deployOrder;
}
/**
* Set the order this property appears in the bean.
*/
public void setDeployOrder(int deployOrder) {
this.deployOrder = deployOrder;
}
public ElPropertyValue buildElPropertyValue(String propName, String remainder, ElPropertyChainBuilder chain, boolean propertyDeploy) {
return null;
}
/**
* Return the BeanDescriptor that owns this property.
*/
public BeanDescriptor> getBeanDescriptor() {
return descriptor;
}
/**
* Return true is this is a simple scalar property.
*/
public boolean isScalar() {
return true;
}
/**
* Return true if this property should have a DB Column created in DDL.
*/
public boolean isDDLColumn() {
return !formula && !secondaryTable && (aggregation == null);
}
/**
* Return true if this property is based on a formula.
*/
@Override
public boolean isFormula() {
return formula;
}
/**
* Return true if this property maps to the inheritance discriminator column.
*/
public boolean isDiscriminator() {
return discriminator;
}
/**
* Return true if the underlying type is mutable.
*/
public boolean isMutableScalarType() {
return scalarType != null && scalarType.isMutable();
}
/**
* Return the encrypt key for the column matching this property.
*/
public EncryptKey getEncryptKey() {
return descriptor.getEncryptKey(this);
}
@Override
public String getEncryptKeyAsString() {
return getEncryptKey().getStringValue();
}
public String getDecryptProperty(String propertyName) {
return dbEncryptFunction.getDecryptSql(propertyName);
}
public String getDecryptSql() {
return dbEncryptFunction.getDecryptSql(this.getDbColumn());
}
public String getDecryptSql(String tableAlias) {
return dbEncryptFunction.getDecryptSql(tableAlias + "." + this.getDbColumn());
}
@Override
public int getFetchPreference() {
// return some decently high value - override on ToMany property
return 1000;
}
/**
* Add any extra joins required to support this property. Generally a no
* operation except for a OneToOne exported.
*/
@Override
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
if (formula && sqlFormulaJoin != null) {
ctx.appendFormulaJoin(sqlFormulaJoin, joinType);
} else if (secondaryTableJoin != null) {
String relativePrefix = ctx.getRelativePrefix(secondaryTableJoinPrefix);
secondaryTableJoin.addJoin(joinType, relativePrefix, ctx);
}
}
/**
* Returns null unless this property is using a secondary table. In that
* case this returns the logical property prefix.
*/
public String getSecondaryTableJoinPrefix() {
return secondaryTableJoinPrefix;
}
@Override
public boolean isAggregation() {
return aggregation != null;
}
@Override
public void appendSelect(DbSqlContext ctx, boolean subQuery) {
if (aggregation != null) {
ctx.appendFormulaSelect(aggregation);
} else if (formula) {
ctx.appendFormulaSelect(sqlFormulaSelect);
} else if (!isTransient && !ignoreDraftOnlyProperty(ctx.isDraftQuery())) {
if (secondaryTableJoin != null) {
ctx.pushTableAlias(ctx.getRelativePrefix(secondaryTableJoinPrefix));
}
if (dbEncrypted) {
String decryptSql = getDecryptSql(ctx.peekTableAlias());
ctx.appendRawColumn(decryptSql);
ctx.addEncryptedProp(this);
} else {
ctx.appendColumn(dbColumn);
}
if (secondaryTableJoin != null) {
ctx.popTableAlias();
}
}
}
@Override
public boolean isMany() {
return false;
}
public boolean isAssignableFrom(Class> type) {
return owningType.isAssignableFrom(type);
}
@Override
public void loadIgnore(DbReadContext ctx) {
scalarType.loadIgnore(ctx.getDataReader());
}
@Override
public void load(SqlBeanLoad sqlBeanLoad) {
sqlBeanLoad.load(this);
}
@Override
public void buildRawSqlSelectChain(String prefix, List selectChain) {
if (prefix == null) {
selectChain.add(name);
} else {
selectChain.add(prefix + "." + name);
}
}
public Object read(DbReadContext ctx) throws SQLException {
return scalarType.read(ctx.getDataReader());
}
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException {
try {
Object value = scalarType.read(ctx.getDataReader());
if (bean != null) {
setValue(bean, value);
}
return value;
} catch (Exception e) {
throw new PersistenceException("Error readSet on " + descriptor + "." + name, e);
}
}
@SuppressWarnings("unchecked")
public void bind(DataBind b, Object value) throws SQLException {
scalarType.bind(b, value);
}
@SuppressWarnings(value = "unchecked")
public void writeData(DataOutput dataOutput, Object value) throws IOException {
scalarType.writeData(dataOutput, value);
}
public Object readData(DataInput dataInput) throws IOException {
return scalarType.readData(dataInput);
}
@Override
public BeanProperty getBeanProperty() {
return this;
}
/**
* Return true if this object is part of an inheritance hierarchy.
*/
public boolean isInherited() {
return inherited;
}
/**
* Return true is this type is not from a super type.
*/
public boolean isLocal() {
return local;
}
/**
* Copy/set the property value from the draft bean to the live bean.
*/
public void publish(EntityBean draftBean, EntityBean liveBean) {
if (!version && !draftOnly) {
// set property value from draft to live
Object value = getValueIntercept(draftBean);
setValueIntercept(liveBean, value);
}
}
/**
* Return the DB literal expression to set the deleted state to true.
*/
public String getSoftDeleteDbSet() {
return softDeleteDbSet;
}
/**
* Return the DB literal predicate used to filter out soft deleted rows from a query.
*/
public String getSoftDeleteDbPredicate(String tableAlias) {
return tableAlias + softDeleteDbPredicate;
}
/**
* Set the soft delete property value on the bean without invoking lazy loading.
*/
public void setSoftDeleteValue(EntityBean bean) {
// assumes boolean deleted true being set which is ok limitation for now
setValue(bean, true);
bean._ebean_getIntercept().setChangedProperty(propertyIndex);
}
/**
* Set the changed value without invoking interception (lazy loading etc).
* Typically used to set generated values on update.
*/
public void setValueChanged(EntityBean bean, Object value) {
setValue(bean, value);
bean._ebean_getIntercept().setChangedProperty(propertyIndex);
}
/**
* Add the tenantId predicate to the query.
*/
public void addTenant(SpiQuery> query, Object tenantId) {
query.where().eq(name, tenantId);
}
/**
* Set the tenantId onto the bean.
*/
public void setTenantValue(EntityBean entityBean, Object tenantId) {
setValue(entityBean, tenantId);
}
/**
* Set the value of the property without interception or
* PropertyChangeSupport.
*/
public void setValue(EntityBean bean, Object value) {
try {
setter.set(bean, value);
} catch (Exception ex) {
throw new RuntimeException(setterErrorMsg(bean, value, "set "), ex);
}
}
/**
* Set the value of the property.
*/
public void setValueIntercept(EntityBean bean, Object value) {
try {
setter.setIntercept(bean, value);
} catch (Exception ex) {
throw new RuntimeException(setterErrorMsg(bean, value, "setIntercept "), ex);
}
}
/**
* Return an error message when calling a setter.
*/
private String setterErrorMsg(EntityBean bean, Object value, String prefix) {
String beanType = bean == null ? "null" : bean.getClass().getName();
return prefix + name + " on [" + descriptor + "] arg[" + value + "] type[" + beanType + "] threw error";
}
/**
* Return true if this property should be included in the cache bean data.
*/
public boolean isCacheDataInclude() {
return true;
}
/**
* Return the value for this property which we hold in the L2 cache entry.
*
* This uses format() where possible to store the value as a string and this
* is done to make any resulting Java object serialisation content smaller as
* strings get special treatment.
*
*/
public Object getCacheDataValue(EntityBean bean) {
Object value = getValue(bean);
if (value == null || scalarType.isBinaryType()) {
return value;
} else {
// convert to string as an optimisation for java object serialisation
return scalarType.format(value);
}
}
/**
* Read the value for this property from L2 cache entry and set it to the bean.
*
* This uses parse() as per the comment in getCacheDataValue().
*
*/
public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) {
if (cacheData instanceof String) {
// parse back from string to support optimisation of java object serialisation
cacheData = scalarType.parse((String) cacheData);
}
setValue(bean, cacheData);
}
@Override
public Object getVal(Object bean) {
return getValue((EntityBean) bean);
}
/**
* Return the value of the property method.
*/
public Object getValue(EntityBean bean) {
try {
return getter.get(bean);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "get " + name + " on [" + descriptor + "] type[" + beanType + "] threw error.";
throw new RuntimeException(msg, ex);
}
}
public Object getValueIntercept(EntityBean bean) {
try {
return getter.getIntercept(bean);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "getIntercept " + name + " on [" + descriptor + "] type[" + beanType + "] threw error.";
throw new RuntimeException(msg, ex);
}
}
@Override
public Object convert(Object value) {
if (value == null) {
return null;
}
return convertToLogicalType(value);
}
@Override
public void pathSet(Object bean, Object value) {
if (bean != null) {
Object logicalVal = convertToLogicalType(value);
setValueIntercept((EntityBean) bean, logicalVal);
}
}
@Override
public Object pathGet(Object bean) {
if (bean == null) {
return null;
}
return getValueIntercept((EntityBean) bean);
}
@Override
public Object pathGetNested(Object bean) {
throw new RuntimeException("Not expected to call this");
}
/**
* Return the name of the property.
*/
@Override
public String getName() {
return name;
}
/**
* Return the position of this property in the enhanced bean.
*/
public int getPropertyIndex() {
return propertyIndex;
}
@Override
public String getElName() {
return name;
}
@Override
public boolean containsFormulaWithJoin() {
return formula && sqlFormulaJoin != null;
}
@Override
public boolean containsManySince(String sinceProperty) {
return containsMany();
}
@Override
public boolean containsMany() {
return aggregation != null;
}
@Override
public String getAssocIsEmpty(SpiExpressionRequest request, String path) {
// overridden in BanePropertyAssocMany
throw new RuntimeException("Not Supported or Expected");
}
@Override
public Object[] getAssocIdValues(EntityBean bean) {
// Returns null as not an AssocOne.
return null;
}
@Override
public String getAssocIdExpression(String prefix, String operator) {
// Returns null as not an AssocOne.
return null;
}
@Override
public String getAssocIdInExpr(String prefix) {
// Returns null as not an AssocOne.
return null;
}
@Override
public String getAssocIdInValueExpr(boolean not, int size) {
// Returns null as not an AssocOne.
return null;
}
/**
* If true this bean maps to the primary key.
*/
public boolean isImportedPrimaryKey() {
return importedPrimaryKey;
}
@Override
public boolean isAssocMany() {
// Returns false - override in BeanPropertyAssocMany.
return false;
}
@Override
public boolean isAssocId() {
// Returns false - override in BeanPropertyAssocOne.
return false;
}
@Override
public boolean isAssocProperty() {
// Returns false - override in BeanPropertyAssocOne.
return false;
}
@Override
public String getElPlaceholder(boolean encrypted) {
return encrypted ? elPlaceHolderEncrypted : elPlaceHolder;
}
@Override
public String getElPrefix() {
return elPrefix;
}
/**
* Return the full name of this property.
*/
public String getFullBeanName() {
return descriptor.getFullName() + "." + name;
}
/**
* Return true if the mutable value is considered dirty.
* This is only used for 'mutable' scalar types like hstore etc.
*/
public boolean isDirtyValue(Object value) {
return scalarType.isDirty(value);
}
/**
* Return the scalarType.
*/
@SuppressWarnings(value = "unchecked")
public ScalarType
© 2015 - 2025 Weber Informatics LLC | Privacy Policy