Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.mapping;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import javax.persistence.AttributeConverter;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.boot.internal.AttributeConverterDescriptorNonAutoApplicableImpl;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.AttributeConverterDescriptor;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BinaryType;
import org.hibernate.type.RowVersionType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry;
import org.hibernate.type.descriptor.sql.JdbcTypeJavaClassMappings;
import org.hibernate.type.descriptor.sql.LobTypeMappings;
import org.hibernate.type.descriptor.sql.NationalizedTypeMappings;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry;
import org.hibernate.usertype.DynamicParameterizedType;
/**
* Any value that maps to columns.
* @author Gavin King
*/
public class SimpleValue implements KeyValue {
private static final CoreMessageLogger log = CoreLogging.messageLogger( SimpleValue.class );
public static final String DEFAULT_ID_GEN_STRATEGY = "assigned";
private final MetadataImplementor metadata;
private final List columns = new ArrayList();
private final List insertability = new ArrayList();
private final List updatability = new ArrayList();
private String typeName;
private Properties typeParameters;
private boolean isVersion;
private boolean isNationalized;
private boolean isLob;
private Properties identifierGeneratorProperties;
private String identifierGeneratorStrategy = DEFAULT_ID_GEN_STRATEGY;
private String nullValue;
private Table table;
private String foreignKeyName;
private String foreignKeyDefinition;
private boolean alternateUniqueKey;
private boolean cascadeDeleteEnabled;
private AttributeConverterDescriptor attributeConverterDescriptor;
private Type type;
public SimpleValue(MetadataImplementor metadata) {
this.metadata = metadata;
}
public SimpleValue(MetadataImplementor metadata, Table table) {
this( metadata );
this.table = table;
}
public MetadataImplementor getMetadata() {
return metadata;
}
@Override
public ServiceRegistry getServiceRegistry() {
return getMetadata().getMetadataBuildingOptions().getServiceRegistry();
}
@Override
public boolean isCascadeDeleteEnabled() {
return cascadeDeleteEnabled;
}
public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
this.cascadeDeleteEnabled = cascadeDeleteEnabled;
}
public void addColumn(Column column) {
addColumn( column, true, true );
}
public void addColumn(Column column, boolean isInsertable, boolean isUpdatable) {
int index = columns.indexOf( column );
if ( index == -1 ) {
columns.add(column);
insertability.add( isInsertable );
updatability.add( isUpdatable );
}
else {
if ( insertability.get( index ) != isInsertable ) {
throw new IllegalStateException( "Same column is added more than once with different values for isInsertable" );
}
if ( updatability.get( index ) != isUpdatable ) {
throw new IllegalStateException( "Same column is added more than once with different values for isUpdatable" );
}
}
column.setValue( this );
column.setTypeIndex( columns.size() - 1 );
}
public void addFormula(Formula formula) {
columns.add( formula );
insertability.add( false );
updatability.add( false );
}
@Override
public boolean hasFormula() {
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
Object o = iter.next();
if (o instanceof Formula) {
return true;
}
}
return false;
}
@Override
public int getColumnSpan() {
return columns.size();
}
@Override
public Iterator getColumnIterator() {
return columns.iterator();
}
public List getConstraintColumns() {
return columns;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
if ( typeName != null && typeName.startsWith( AttributeConverterTypeAdapter.NAME_PREFIX ) ) {
final String converterClassName = typeName.substring( AttributeConverterTypeAdapter.NAME_PREFIX.length() );
final ClassLoaderService cls = getMetadata().getMetadataBuildingOptions()
.getServiceRegistry()
.getService( ClassLoaderService.class );
try {
final Class converterClass = cls.classForName( converterClassName );
attributeConverterDescriptor = new AttributeConverterDescriptorNonAutoApplicableImpl( converterClass.newInstance() );
return;
}
catch (Exception e) {
log.logBadHbmAttributeConverterType( typeName, e.getMessage() );
}
}
this.typeName = typeName;
}
public void makeVersion() {
this.isVersion = true;
}
public boolean isVersion() {
return isVersion;
}
public void makeNationalized() {
this.isNationalized = true;
}
public boolean isNationalized() {
return isNationalized;
}
public void makeLob() {
this.isLob = true;
}
public boolean isLob() {
return isLob;
}
public void setTable(Table table) {
this.table = table;
}
@Override
public void createForeignKey() throws MappingException {}
@Override
public void createForeignKeyOfEntity(String entityName) {
if ( !hasFormula() && !"none".equals(getForeignKeyName())) {
ForeignKey fk = table.createForeignKey( getForeignKeyName(), getConstraintColumns(), entityName, getForeignKeyDefinition() );
fk.setCascadeDeleteEnabled(cascadeDeleteEnabled);
}
}
private IdentifierGenerator identifierGenerator;
@Override
public IdentifierGenerator createIdentifierGenerator(
IdentifierGeneratorFactory identifierGeneratorFactory,
Dialect dialect,
String defaultCatalog,
String defaultSchema,
RootClass rootClass) throws MappingException {
if ( identifierGenerator != null ) {
return identifierGenerator;
}
Properties params = new Properties();
//if the hibernate-mapping did not specify a schema/catalog, use the defaults
//specified by properties - but note that if the schema/catalog were specified
//in hibernate-mapping, or as params, they will already be initialized and
//will override the values set here (they are in identifierGeneratorProperties)
if ( defaultSchema!=null ) {
params.setProperty(PersistentIdentifierGenerator.SCHEMA, defaultSchema);
}
if ( defaultCatalog!=null ) {
params.setProperty(PersistentIdentifierGenerator.CATALOG, defaultCatalog);
}
//pass the entity-name, if not a collection-id
if (rootClass!=null) {
params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() );
}
//init the table here instead of earlier, so that we can get a quoted table name
//TODO: would it be better to simply pass the qualified table name, instead of
// splitting it up into schema/catalog/table names
String tableName = getTable().getQuotedName(dialect);
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
//pass the column name (a generated id almost always has a single column)
String columnName = ( (Column) getColumnIterator().next() ).getQuotedName(dialect);
params.setProperty( PersistentIdentifierGenerator.PK, columnName );
if (rootClass!=null) {
StringBuilder tables = new StringBuilder();
Iterator iter = rootClass.getIdentityTables().iterator();
while ( iter.hasNext() ) {
Table table= (Table) iter.next();
tables.append( table.getQuotedName(dialect) );
if ( iter.hasNext() ) {
tables.append(", ");
}
}
params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
}
else {
params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
}
if (identifierGeneratorProperties!=null) {
params.putAll(identifierGeneratorProperties);
}
// TODO : we should pass along all settings once "config lifecycle" is hashed out...
final ConfigurationService cs = metadata.getMetadataBuildingOptions().getServiceRegistry()
.getService( ConfigurationService.class );
params.put(
AvailableSettings.PREFER_POOLED_VALUES_LO,
cs.getSetting( AvailableSettings.PREFER_POOLED_VALUES_LO, StandardConverters.BOOLEAN, false )
);
if ( cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER ) != null ) {
params.put(
AvailableSettings.PREFERRED_POOLED_OPTIMIZER,
cs.getSettings().get( AvailableSettings.PREFERRED_POOLED_OPTIMIZER )
);
}
identifierGeneratorFactory.setDialect( dialect );
identifierGenerator = identifierGeneratorFactory.createIdentifierGenerator( identifierGeneratorStrategy, getType(), params );
return identifierGenerator;
}
public boolean isUpdateable() {
//needed to satisfy KeyValue
return true;
}
public FetchMode getFetchMode() {
return FetchMode.SELECT;
}
public Properties getIdentifierGeneratorProperties() {
return identifierGeneratorProperties;
}
public String getNullValue() {
return nullValue;
}
public Table getTable() {
return table;
}
/**
* Returns the identifierGeneratorStrategy.
* @return String
*/
public String getIdentifierGeneratorStrategy() {
return identifierGeneratorStrategy;
}
public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect) {
identifierGeneratorFactory.setDialect( dialect );
return IdentityGenerator.class.isAssignableFrom(identifierGeneratorFactory.getIdentifierGeneratorClass( identifierGeneratorStrategy ));
}
/**
* Sets the identifierGeneratorProperties.
* @param identifierGeneratorProperties The identifierGeneratorProperties to set
*/
public void setIdentifierGeneratorProperties(Properties identifierGeneratorProperties) {
this.identifierGeneratorProperties = identifierGeneratorProperties;
}
/**
* Sets the identifierGeneratorStrategy.
* @param identifierGeneratorStrategy The identifierGeneratorStrategy to set
*/
public void setIdentifierGeneratorStrategy(String identifierGeneratorStrategy) {
this.identifierGeneratorStrategy = identifierGeneratorStrategy;
}
/**
* Sets the nullValue.
* @param nullValue The nullValue to set
*/
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
public String getForeignKeyName() {
return foreignKeyName;
}
public void setForeignKeyName(String foreignKeyName) {
this.foreignKeyName = foreignKeyName;
}
public String getForeignKeyDefinition() {
return foreignKeyDefinition;
}
public void setForeignKeyDefinition(String foreignKeyDefinition) {
this.foreignKeyDefinition = foreignKeyDefinition;
}
public boolean isAlternateUniqueKey() {
return alternateUniqueKey;
}
public void setAlternateUniqueKey(boolean unique) {
this.alternateUniqueKey = unique;
}
public boolean isNullable() {
Iterator itr = getColumnIterator();
while ( itr.hasNext() ) {
final Object selectable = itr.next();
if ( selectable instanceof Formula ) {
// if there are *any* formulas, then the Value overall is
// considered nullable
return true;
}
else if ( !( (Column) selectable ).isNullable() ) {
// if there is a single non-nullable column, the Value
// overall is considered non-nullable.
return false;
}
}
// nullable by default
return true;
}
public boolean isSimpleValue() {
return true;
}
public boolean isValid(Mapping mapping) throws MappingException {
return getColumnSpan()==getType().getColumnSpan(mapping);
}
public Type getType() throws MappingException {
if ( type != null ) {
return type;
}
if ( typeName == null ) {
throw new MappingException( "No type name" );
}
if ( typeParameters != null
&& Boolean.valueOf( typeParameters.getProperty( DynamicParameterizedType.IS_DYNAMIC ) )
&& typeParameters.get( DynamicParameterizedType.PARAMETER_TYPE ) == null ) {
createParameterImpl();
}
Type result = metadata.getTypeResolver().heuristicType( typeName, typeParameters );
// if this is a byte[] version/timestamp, then we need to use RowVersionType
// instead of BinaryType (HHH-10413)
if ( isVersion && BinaryType.class.isInstance( result ) ) {
log.debug( "version is BinaryType; changing to RowVersionType" );
result = RowVersionType.INSTANCE;
}
if ( result == null ) {
String msg = "Could not determine type for: " + typeName;
if ( table != null ) {
msg += ", at table: " + table.getName();
}
if ( columns != null && columns.size() > 0 ) {
msg += ", for columns: " + columns;
}
throw new MappingException( msg );
}
return result;
}
public void setTypeUsingReflection(String className, String propertyName) throws MappingException {
// NOTE : this is called as the last piece in setting SimpleValue type information, and implementations
// rely on that fact, using it as a signal that all information it is going to get is defined at this point...
if ( typeName != null ) {
// assume either (a) explicit type was specified or (b) determine was already performed
return;
}
if ( type != null ) {
return;
}
if ( attributeConverterDescriptor == null ) {
// this is here to work like legacy. This should change when we integrate with metamodel to
// look for SqlTypeDescriptor and JavaTypeDescriptor individually and create the BasicType (well, really
// keep a registry of [SqlTypeDescriptor,JavaTypeDescriptor] -> BasicType...)
if ( className == null ) {
throw new MappingException( "Attribute types for a dynamic entity must be explicitly specified: " + propertyName );
}
typeName = ReflectHelper.reflectedPropertyClass( className, propertyName, metadata.getMetadataBuildingOptions().getServiceRegistry().getService( ClassLoaderService.class ) ).getName();
// todo : to fully support isNationalized here we need do the process hinted at above
// essentially, much of the logic from #buildAttributeConverterTypeAdapter wrt resolving
// a (1) SqlTypeDescriptor, a (2) JavaTypeDescriptor and dynamically building a BasicType
// combining them.
return;
}
// we had an AttributeConverter...
type = buildAttributeConverterTypeAdapter();
}
/**
* Build a Hibernate Type that incorporates the JPA AttributeConverter. AttributeConverter works totally in
* memory, meaning it converts between one Java representation (the entity attribute representation) and another
* (the value bound into JDBC statements or extracted from results). However, the Hibernate Type system operates
* at the lower level of actually dealing directly with those JDBC objects. So even though we have an
* AttributeConverter, we still need to "fill out" the rest of the BasicType data and bridge calls
* to bind/extract through the converter.
*
* Essentially the idea here is that an intermediate Java type needs to be used. Let's use an example as a means
* to illustrate... Consider an {@code AttributeConverter}. This tells Hibernate that the domain
* model defines this attribute as an Integer value (the 'entityAttributeJavaType'), but that we need to treat the
* value as a String (the 'databaseColumnJavaType') when dealing with JDBC (aka, the database type is a
* VARCHAR/CHAR):