HHH-6257 : Add IdentifierGenerator to EntityIdentifier binding
This commit is contained in:
parent
edb264ae15
commit
f90f224f60
|
@ -68,6 +68,16 @@ public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFac
|
|||
private transient Dialect dialect;
|
||||
private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>();
|
||||
|
||||
/**
|
||||
* Constructs a new DefaultIdentifierGeneratorFactory
|
||||
*
|
||||
* @param dialect The dialect.
|
||||
*/
|
||||
public DefaultIdentifierGeneratorFactory(Dialect dialect) {
|
||||
this();
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new DefaultIdentifierGeneratorFactory.
|
||||
*/
|
||||
|
@ -97,6 +107,10 @@ public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFac
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDialect(Dialect dialect) {
|
||||
|
|
|
@ -34,6 +34,12 @@ import org.hibernate.type.Type;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface IdentifierGeneratorFactory {
|
||||
/**
|
||||
* Get the dialect.
|
||||
*
|
||||
* @return the dialect
|
||||
*/
|
||||
public Dialect getDialect();
|
||||
|
||||
/**
|
||||
* Allow injection of the dialect to use.
|
||||
|
|
|
@ -178,7 +178,7 @@ public final class SessionFactoryImpl
|
|||
private final transient Map collectionPersisters;
|
||||
private final transient Map collectionMetadata;
|
||||
private final transient Map<String,Set<String>> collectionRolesByEntityParticipant;
|
||||
private final transient Map identifierGenerators;
|
||||
private final transient Map<String,IdentifierGenerator> identifierGenerators;
|
||||
private final transient Map<String, NamedQueryDefinition> namedQueries;
|
||||
private final transient Map<String, NamedSQLQueryDefinition> namedSqlQueries;
|
||||
private final transient Map<String, ResultSetMappingDefinition> sqlResultSetMappings;
|
||||
|
@ -600,16 +600,13 @@ public final class SessionFactoryImpl
|
|||
|
||||
//Generators:
|
||||
|
||||
identifierGenerators = new HashMap();
|
||||
identifierGenerators = new HashMap<String,IdentifierGenerator>();
|
||||
for ( EntityBinding entityBinding : metadata.getEntityBindings() ) {
|
||||
if ( entityBinding.isRoot() ) {
|
||||
// TODO: create the IdentifierGenerator while the metadata is being build, then simply
|
||||
// use EntityBinding.getIdentifierGenerator() (also remove getIdentifierGeneratorFactory from Mappings)
|
||||
// TODO: this is broken; throws NullPointerException
|
||||
//IdentifierGenerator generator = entityBinding.getEntityIdentifier().createIdentifierGenerator(
|
||||
// metadata.getIdentifierGeneratorFactory()
|
||||
//);
|
||||
//identifierGenerators.put( entityBinding.getEntity().getName(), generator );
|
||||
identifierGenerators.put(
|
||||
entityBinding.getEntity().getName(),
|
||||
entityBinding.getEntityIdentifier().getIdentifierGenerator()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,17 +84,9 @@ public class EntityIdentifier {
|
|||
return isIdentifierMapper;
|
||||
}
|
||||
|
||||
public IdentifierGenerator createIdentifierGenerator(IdentifierGeneratorFactory factory) {
|
||||
if ( identifierGenerator == null ) {
|
||||
Properties props = new Properties();
|
||||
if ( idGenerator != null ) {
|
||||
props.putAll( idGenerator.getParameters() );
|
||||
}
|
||||
identifierGenerator = factory.createIdentifierGenerator(
|
||||
idGenerator.getStrategy(),
|
||||
getValueBinding().getHibernateTypeDescriptor().getResolvedTypeMapping(),
|
||||
props
|
||||
);
|
||||
public IdentifierGenerator createIdentifierGenerator(IdentifierGeneratorFactory factory, Properties properties) {
|
||||
if ( idGenerator != null ) {
|
||||
identifierGenerator = attributeBinding.createIdentifierGenerator( idGenerator, factory, properties );
|
||||
}
|
||||
return identifierGenerator;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,13 @@ public class IdGenerator implements Serializable {
|
|||
* @return generator configuration parameters
|
||||
*/
|
||||
public Map<String, String> getParameters() {
|
||||
return Collections.unmodifiableMap(parameters);
|
||||
Map<String, String> returnedParameters;
|
||||
if ( parameters == null ) {
|
||||
returnedParameters = Collections.emptyMap();
|
||||
}
|
||||
else {
|
||||
returnedParameters = Collections.unmodifiableMap(parameters);
|
||||
}
|
||||
return returnedParameters;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,17 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.binding;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.domain.AbstractAttributeContainer;
|
||||
import org.hibernate.metamodel.relational.Column;
|
||||
import org.hibernate.metamodel.relational.Schema;
|
||||
import org.hibernate.metamodel.relational.SimpleValue;
|
||||
import org.hibernate.metamodel.source.MetaAttributeContext;
|
||||
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
|
||||
import org.hibernate.metamodel.domain.SingularAttribute;
|
||||
|
@ -159,4 +168,77 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
|
|||
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
|
||||
this.metaAttributeContext = metaAttributeContext;
|
||||
}
|
||||
|
||||
/* package-protected */
|
||||
IdentifierGenerator createIdentifierGenerator(
|
||||
IdGenerator idGenerator,
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Properties properties) {
|
||||
Properties params = new Properties();
|
||||
params.putAll( properties );
|
||||
|
||||
// use the schema/catalog specified by getValue().getTable() - but note that
|
||||
// if the schema/catalog were specified as params, they will already be initialized and
|
||||
//will override the values set here (they are in idGenerator.getParameters().)
|
||||
Schema schema = getValue().getTable().getSchema();
|
||||
if ( schema != null ) {
|
||||
if ( schema.getName().getSchema() != null ) {
|
||||
params.setProperty( PersistentIdentifierGenerator.SCHEMA, schema.getName().getSchema().getName() );
|
||||
}
|
||||
if ( schema.getName().getCatalog() != null ) {
|
||||
params.setProperty(PersistentIdentifierGenerator.CATALOG, schema.getName().getCatalog().getName() );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: not sure how this works for collection IDs...
|
||||
//pass the entity-name, if not a collection-id
|
||||
//if ( rootClass!=null) {
|
||||
params.setProperty( IdentifierGenerator.ENTITY_NAME, getEntityBinding().getEntity().getName() );
|
||||
//}
|
||||
|
||||
//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 = getValue().getTable().getQualifiedName( identifierGeneratorFactory.getDialect() );
|
||||
params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
|
||||
|
||||
//pass the column name (a generated id almost always has a single column)
|
||||
if ( getValuesSpan() != 1 ) {
|
||||
throw new MappingException( "A SimpleAttributeBinding has a more than 1 Value: " + getAttribute().getName() );
|
||||
}
|
||||
SimpleValue simpleValue = getValues().iterator().next();
|
||||
if ( ! Column.class.isInstance( simpleValue ) ) {
|
||||
throw new MappingException(
|
||||
"Cannot create an IdentifierGenerator because the value is not a column: " +
|
||||
simpleValue.toLoggableString()
|
||||
);
|
||||
}
|
||||
params.setProperty(
|
||||
PersistentIdentifierGenerator.PK,
|
||||
( ( Column ) simpleValue ).getColumnName().encloseInQuotesIfQuoted(
|
||||
identifierGeneratorFactory.getDialect()
|
||||
)
|
||||
);
|
||||
|
||||
// TODO: is this stuff necessary for SimpleValue???
|
||||
//if (rootClass!=null) {
|
||||
// StringBuffer tables = new StringBuffer();
|
||||
// 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 );
|
||||
//}
|
||||
|
||||
params.putAll( idGenerator.getParameters() );
|
||||
|
||||
return identifierGeneratorFactory.createIdentifierGenerator(
|
||||
idGenerator.getStrategy(), getHibernateTypeDescriptor().getResolvedTypeMapping(), params
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.metamodel.source.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.NamingStrategy;
|
||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||
import org.hibernate.service.config.spi.ConfigurationService;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class IdentifierGeneratorResolver {
|
||||
|
||||
private final MetadataImplementor metadata;
|
||||
|
||||
IdentifierGeneratorResolver(MetadataImplementor metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
// IdentifierGeneratorResolver.resolve() must execute after AttributeTypeResolver.resolve()
|
||||
// to ensure that identifier type is resolved.
|
||||
@SuppressWarnings( {"unchecked"} )
|
||||
void resolve() {
|
||||
for ( EntityBinding entityBinding : metadata.getEntityBindings() ) {
|
||||
if ( entityBinding.isRoot() ) {
|
||||
Properties properties = new Properties( );
|
||||
properties.putAll(
|
||||
metadata.getServiceRegistry()
|
||||
.getService( ConfigurationService.class )
|
||||
.getSettings()
|
||||
);
|
||||
//TODO: where should these be added???
|
||||
if ( ! properties.contains( AvailableSettings.PREFER_POOLED_VALUES_LO ) ) {
|
||||
properties.put( AvailableSettings.PREFER_POOLED_VALUES_LO, "false" );
|
||||
}
|
||||
if ( ! properties.contains( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER ) ) {
|
||||
properties.put(
|
||||
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
|
||||
new ObjectNameNormalizerImpl( metadata )
|
||||
);
|
||||
}
|
||||
entityBinding.getEntityIdentifier().createIdentifierGenerator(
|
||||
metadata.getIdentifierGeneratorFactory(),
|
||||
properties
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ObjectNameNormalizerImpl extends ObjectNameNormalizer implements Serializable {
|
||||
private final boolean useQuotedIdentifiersGlobally;
|
||||
private final NamingStrategy namingStrategy;
|
||||
|
||||
private ObjectNameNormalizerImpl(MetadataImplementor metadata ) {
|
||||
this.useQuotedIdentifiersGlobally = metadata.isGloballyQuotedIdentifiers();
|
||||
this.namingStrategy = metadata.getNamingStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isUseQuotedIdentifiersGlobally() {
|
||||
return useQuotedIdentifiersGlobally;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NamingStrategy getNamingStrategy() {
|
||||
return namingStrategy;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,7 +38,9 @@ import org.hibernate.SessionFactory;
|
|||
import org.hibernate.cache.spi.RegionFactory;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cfg.NamingStrategy;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.FilterDefinition;
|
||||
import org.hibernate.engine.spi.NamedQueryDefinition;
|
||||
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
|
||||
|
@ -93,7 +95,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
|
||||
private SessionFactoryBuilder sessionFactoryBuilder = new SessionFactoryBuilderImpl( this );
|
||||
|
||||
private DefaultIdentifierGeneratorFactory identifierGeneratorFactory = new DefaultIdentifierGeneratorFactory();
|
||||
private final DefaultIdentifierGeneratorFactory identifierGeneratorFactory;
|
||||
|
||||
private final Database database;
|
||||
|
||||
|
@ -117,8 +119,10 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
private boolean globallyQuotedIdentifiers = false;
|
||||
|
||||
public MetadataImpl(MetadataSources metadataSources, Options options) {
|
||||
Dialect dialect = metadataSources.getServiceRegistry().getService( JdbcServices.class ).getDialect();
|
||||
this.serviceRegistry = metadataSources.getServiceRegistry();
|
||||
this.options = options;
|
||||
this.identifierGeneratorFactory = new DefaultIdentifierGeneratorFactory( dialect );
|
||||
this.database = new Database( options );
|
||||
|
||||
this.mappingDefaults = new MappingDefaultsImpl();
|
||||
|
@ -166,6 +170,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
|||
// todo : remove this by coordinated ordering of entity processing
|
||||
new EntityReferenceResolver( this ).resolve();
|
||||
new AttributeTypeResolver( this ).resolve();
|
||||
// IdentifierGeneratorResolver.resolve() must execute after AttributeTypeResolver.resolve()
|
||||
new IdentifierGeneratorResolver( this ).resolve();
|
||||
}
|
||||
|
||||
private void prepare(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources) {
|
||||
|
|
Loading…
Reference in New Issue