HHH-4553 - Hibernate doesn't support official JPA2 escape char for table name

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18148 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2009-12-06 22:20:58 +00:00
parent ecb103cf55
commit a2bf14ae7c
23 changed files with 880 additions and 217 deletions

View File

@ -395,6 +395,7 @@ public final class AnnotationBinder {
idGen.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, seqGen.sequenceName() ); idGen.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, seqGen.sequenceName() );
} }
//FIXME: work on initialValue() through SequenceGenerator.PARAMETERS //FIXME: work on initialValue() through SequenceGenerator.PARAMETERS
// steve : or just use o.h.id.enhanced.SequenceStyleGenerator
if ( seqGen.initialValue() != 1 ) { if ( seqGen.initialValue() != 1 ) {
log.warn( log.warn(
"Hibernate does not support SequenceGenerator.initialValue()" "Hibernate does not support SequenceGenerator.initialValue()"
@ -485,7 +486,7 @@ public final class AnnotationBinder {
String table = ""; //might be no @Table annotation on the annotated class String table = ""; //might be no @Table annotation on the annotated class
String catalog = ""; String catalog = "";
String discrimValue = null; String discrimValue = null;
List<String[]> uniqueConstraints = new ArrayList<String[]>(); List<UniqueConstraintHolder> uniqueConstraints = new ArrayList<UniqueConstraintHolder>();
Ejb3DiscriminatorColumn discriminatorColumn = null; Ejb3DiscriminatorColumn discriminatorColumn = null;
Ejb3JoinColumn[] inheritanceJoinedColumns = null; Ejb3JoinColumn[] inheritanceJoinedColumns = null;
@ -494,7 +495,7 @@ public final class AnnotationBinder {
table = tabAnn.name(); table = tabAnn.name();
schema = tabAnn.schema(); schema = tabAnn.schema();
catalog = tabAnn.catalog(); catalog = tabAnn.catalog();
uniqueConstraints = TableBinder.buildUniqueConstraints( tabAnn.uniqueConstraints() ); uniqueConstraints = TableBinder.buildUniqueConstraintHolders( tabAnn.uniqueConstraints() );
} }
final boolean hasJoinedColumns = inheritanceState.hasParents final boolean hasJoinedColumns = inheritanceState.hasParents
&& InheritanceType.JOINED.equals( inheritanceState.type ); && InheritanceType.JOINED.equals( inheritanceState.type );

View File

@ -85,6 +85,7 @@ import org.hibernate.mapping.UniqueKey;
import org.hibernate.util.JoinedIterator; import org.hibernate.util.JoinedIterator;
import org.hibernate.util.ReflectHelper; import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.hibernate.util.CollectionHelper;
/** /**
* Similar to the {@link Configuration} object but handles EJB3 and Hibernate * Similar to the {@link Configuration} object but handles EJB3 and Hibernate
@ -121,7 +122,8 @@ public class AnnotationConfiguration extends Configuration {
private Set<String> defaultSqlResulSetMappingNames; private Set<String> defaultSqlResulSetMappingNames;
private Set<String> defaultNamedGenerators; private Set<String> defaultNamedGenerators;
private Map<String, Properties> generatorTables; private Map<String, Properties> generatorTables;
private Map<Table, List<String[]>> tableUniqueConstraints; private Map<Table, List<UniqueConstraintHolder>> uniqueConstraintHoldersByTable;
// private Map<Table, List<String[]>> tableUniqueConstraints;
private Map<String, String> mappedByResolver; private Map<String, String> mappedByResolver;
private Map<String, String> propertyRefResolver; private Map<String, String> propertyRefResolver;
private Map<String, AnyMetaDef> anyMetaDefs; private Map<String, AnyMetaDef> anyMetaDefs;
@ -249,7 +251,7 @@ public class AnnotationConfiguration extends Configuration {
defaultNamedNativeQueryNames = new HashSet<String>(); defaultNamedNativeQueryNames = new HashSet<String>();
defaultSqlResulSetMappingNames = new HashSet<String>(); defaultSqlResulSetMappingNames = new HashSet<String>();
defaultNamedGenerators = new HashSet<String>(); defaultNamedGenerators = new HashSet<String>();
tableUniqueConstraints = new HashMap<Table, List<String[]>>(); uniqueConstraintHoldersByTable = new HashMap<Table, List<UniqueConstraintHolder>>();
mappedByResolver = new HashMap<String, String>(); mappedByResolver = new HashMap<String, String>();
propertyRefResolver = new HashMap<String, String>(); propertyRefResolver = new HashMap<String, String>();
annotatedClasses = new ArrayList<XClass>(); annotatedClasses = new ArrayList<XClass>();
@ -358,19 +360,19 @@ public class AnnotationConfiguration extends Configuration {
//the exception was not recoverable after all //the exception was not recoverable after all
throw ( RuntimeException ) e.getCause(); throw ( RuntimeException ) e.getCause();
} }
Iterator tables = tableUniqueConstraints.entrySet().iterator();
Table table; Iterator<Map.Entry<Table,List<UniqueConstraintHolder>>> tables = uniqueConstraintHoldersByTable.entrySet().iterator();
Map.Entry entry;
String keyName;
int uniqueIndexPerTable;
while ( tables.hasNext() ) { while ( tables.hasNext() ) {
entry = ( Map.Entry ) tables.next(); final Map.Entry<Table,List<UniqueConstraintHolder>> entry = tables.next();
table = ( Table ) entry.getKey(); final Table table = entry.getKey();
List<String[]> uniqueConstraints = ( List<String[]> ) entry.getValue(); final List<UniqueConstraintHolder> uniqueConstraints = entry.getValue();
uniqueIndexPerTable = 0; int uniqueIndexPerTable = 0;
for ( String[] columnNames : uniqueConstraints ) { for ( UniqueConstraintHolder holder : uniqueConstraints ) {
keyName = "key" + uniqueIndexPerTable++; uniqueIndexPerTable++;
buildUniqueKeyFromColumnNames( columnNames, table, keyName ); final String keyName = StringHelper.isEmpty( holder.getName() )
? "key" + uniqueIndexPerTable
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
} }
} }
applyConstraintsToDDL(); applyConstraintsToDDL();
@ -621,23 +623,26 @@ public class AnnotationConfiguration extends Configuration {
} }
} }
private void buildUniqueKeyFromColumnNames(String[] columnNames, Table table, String keyName) { private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames) {
ExtendedMappings mappings = createExtendedMappings();
keyName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( keyName );
UniqueKey uc; UniqueKey uc;
int size = columnNames.length; int size = columnNames.length;
Column[] columns = new Column[size]; Column[] columns = new Column[size];
Set<Column> unbound = new HashSet<Column>(); Set<Column> unbound = new HashSet<Column>();
Set<Column> unboundNoLogical = new HashSet<Column>(); Set<Column> unboundNoLogical = new HashSet<Column>();
ExtendedMappings mappings = createExtendedMappings();
for ( int index = 0; index < size; index++ ) { for ( int index = 0; index < size; index++ ) {
String columnName; final String logicalColumnName = mappings.getObjectNameNormalizer()
.normalizeIdentifierQuoting( columnNames[index] );
try { try {
columnName = mappings.getPhysicalColumnName( columnNames[index], table ); final String columnName = mappings.getPhysicalColumnName( logicalColumnName, table );
columns[index] = new Column( columnName ); columns[index] = new Column( columnName );
unbound.add( columns[index] ); unbound.add( columns[index] );
//column equals and hashcode is based on column name //column equals and hashcode is based on column name
} }
catch ( MappingException e ) { catch ( MappingException e ) {
unboundNoLogical.add( new Column( columnNames[index] ) ); unboundNoLogical.add( new Column( logicalColumnName ) );
} }
} }
for ( Column column : columns ) { for ( Column column : columns ) {
@ -1258,17 +1263,69 @@ public class AnnotationConfiguration extends Configuration {
return type; return type;
} }
/**
* {@inheritDoc}
*/
public Map<Table, List<String[]>> getTableUniqueConstraints() { public Map<Table, List<String[]>> getTableUniqueConstraints() {
return tableUniqueConstraints; final Map<Table, List<String[]>> deprecatedStructure = new HashMap<Table, List<String[]>>(
CollectionHelper.determineProperSizing( getUniqueConstraintHoldersByTable() ),
CollectionHelper.LOAD_FACTOR
);
for ( Map.Entry<Table, List<UniqueConstraintHolder>> entry : getUniqueConstraintHoldersByTable().entrySet() ) {
List<String[]> columnsPerConstraint = new ArrayList<String[]>(
CollectionHelper.determineProperSizing( entry.getValue().size() )
);
deprecatedStructure.put( entry.getKey(), columnsPerConstraint );
for ( UniqueConstraintHolder holder : entry.getValue() ) {
columnsPerConstraint.add( holder.getColumns() );
}
}
return deprecatedStructure;
} }
/**
* {@inheritDoc}
*/
public Map<Table, List<UniqueConstraintHolder>> getUniqueConstraintHoldersByTable() {
return uniqueConstraintHoldersByTable;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public void addUniqueConstraints(Table table, List uniqueConstraints) { public void addUniqueConstraints(Table table, List uniqueConstraints) {
List oldConstraints = tableUniqueConstraints.get( table ); List<UniqueConstraintHolder> constraintHolders = new ArrayList<UniqueConstraintHolder>(
if ( oldConstraints == null ) { CollectionHelper.determineProperSizing( uniqueConstraints.size() )
oldConstraints = new ArrayList(); );
tableUniqueConstraints.put( table, oldConstraints );
int keyNameBase = determineCurrentNumberOfUniqueConstraintHolders( table );
for ( String[] columns : (List<String[]>)uniqueConstraints ) {
final String keyName = "key" + keyNameBase++;
constraintHolders.add(
new UniqueConstraintHolder().setName( keyName ).setColumns( columns )
);
} }
oldConstraints.addAll( uniqueConstraints ); addUniqueConstraintHolders( table, constraintHolders );
}
private int determineCurrentNumberOfUniqueConstraintHolders(Table table) {
List currentHolders = getUniqueConstraintHoldersByTable().get( table );
return currentHolders == null
? 0
: currentHolders.size();
}
/**
* {@inheritDoc}
*/
public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder> uniqueConstraintHolders) {
List<UniqueConstraintHolder> holderList = getUniqueConstraintHoldersByTable().get( table );
if ( holderList == null ) {
holderList = new ArrayList<UniqueConstraintHolder>();
getUniqueConstraintHoldersByTable().put( table, holderList );
}
holderList.addAll( uniqueConstraintHolders );
} }
public void addMappedBy(String entityName, String propertyName, String inversePropertyName) { public void addMappedBy(String entityName, String propertyName, String inversePropertyName) {

View File

@ -27,8 +27,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.persistence.MappedSuperclass;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.annotations.AnyMetaDef; import org.hibernate.annotations.AnyMetaDef;
@ -134,10 +132,22 @@ public interface ExtendedMappings extends Mappings {
*/ */
public AnnotatedClassType addClassType(XClass clazz); public AnnotatedClassType addClassType(XClass clazz);
/**
* @deprecated Use {@link #getUniqueConstraintHoldersByTable} instead
*/
@SuppressWarnings({ "JavaDoc" })
public Map<Table, List<String[]>> getTableUniqueConstraints(); public Map<Table, List<String[]>> getTableUniqueConstraints();
public Map<Table, List<UniqueConstraintHolder>> getUniqueConstraintHoldersByTable();
/**
* @deprecated Use {@link #addUniqueConstraintHolders} instead
*/
@SuppressWarnings({ "JavaDoc" })
public void addUniqueConstraints(Table table, List uniqueConstraints); public void addUniqueConstraints(Table table, List uniqueConstraints);
public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder> uniqueConstraintHolders);
public void addMappedBy(String entityName, String propertyName, String inversePropertyName); public void addMappedBy(String entityName, String propertyName, String inversePropertyName);
public String getFromMappedBy(String entityName, String propertyName); public String getFromMappedBy(String entityName, String propertyName);

View File

@ -0,0 +1,55 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.cfg;
/**
* {@link javax.persistence.UniqueConstraint} annotations are handled via second pass. I do not
* understand the reasons why at this time, so here I use a holder object to hold the information
* needed to create the unique constraint. The ability to name it is new, and so the code used to
* simply keep this as a String array (the column names).
*
* @author Steve Ebersole
*/
public class UniqueConstraintHolder {
private String name;
private String[] columns;
public String getName() {
return name;
}
public UniqueConstraintHolder setName(String name) {
this.name = name;
return this;
}
public String[] getColumns() {
return columns;
}
public UniqueConstraintHolder setColumns(String[] columns) {
this.columns = columns;
return this;
}
}

View File

@ -23,7 +23,6 @@
*/ */
package org.hibernate.cfg.annotations; package org.hibernate.cfg.annotations;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -34,7 +33,6 @@ import javax.persistence.JoinTable;
import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable; import javax.persistence.SecondaryTable;
import javax.persistence.SecondaryTables; import javax.persistence.SecondaryTables;
import javax.persistence.UniqueConstraint;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -68,6 +66,10 @@ import org.hibernate.cfg.Ejb3JoinColumn;
import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.InheritanceState; import org.hibernate.cfg.InheritanceState;
import org.hibernate.cfg.PropertyHolder; import org.hibernate.cfg.PropertyHolder;
import org.hibernate.cfg.ObjectNameSource;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.cfg.UniqueConstraintHolder;
import org.hibernate.engine.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.Versioning; import org.hibernate.engine.Versioning;
@ -81,6 +83,7 @@ import org.hibernate.mapping.TableOwner;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.util.ReflectHelper; import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -292,9 +295,7 @@ public class EntityBinder {
} }
if ( !inheritanceState.hasParents ) { if ( !inheritanceState.hasParents ) {
Iterator<Map.Entry<String, String>> iter = filters.entrySet().iterator(); for ( Map.Entry<String, String> filter : filters.entrySet() ) {
while ( iter.hasNext() ) {
Map.Entry<String, String> filter = iter.next();
String filterName = filter.getKey(); String filterName = filter.getKey();
String cond = filter.getValue(); String cond = filter.getValue();
if ( BinderHelper.isDefault( cond ) ) { if ( BinderHelper.isDefault( cond ) ) {
@ -386,6 +387,7 @@ public class EntityBinder {
} }
} }
@SuppressWarnings({ "unchecked" })
public void setProxy(Proxy proxy) { public void setProxy(Proxy proxy) {
if ( proxy != null ) { if ( proxy != null ) {
lazy = proxy.lazy(); lazy = proxy.lazy();
@ -415,29 +417,58 @@ public class EntityBinder {
} }
} }
private String getClassTableName(String tableName) { private static class EntityTableObjectNameSource implements ObjectNameSource {
if ( StringHelper.isEmpty( tableName ) ) { private final String explicitName;
return mappings.getNamingStrategy().classToTableName( name ); private final String logicalName;
private EntityTableObjectNameSource(String explicitName, String entityName) {
this.explicitName = explicitName;
this.logicalName = StringHelper.isNotEmpty( explicitName )
? explicitName
: StringHelper.unqualify( entityName );
} }
else {
return mappings.getNamingStrategy().tableName( tableName ); public String getExplicitName() {
return explicitName;
}
public String getLogicalName() {
return logicalName;
}
}
private static class EntityTableNamingStrategyHelper implements ObjectNameNormalizer.NamingStrategyHelper {
private final String entityName;
private EntityTableNamingStrategyHelper(String entityName) {
this.entityName = entityName;
}
public String determineImplicitName(NamingStrategy strategy) {
return strategy.classToTableName( entityName );
}
public String handleExplicitName(NamingStrategy strategy, String name) {
return strategy.tableName( name );
} }
} }
public void bindTable( public void bindTable(
String schema, String catalog, String schema, String catalog,
String tableName, List uniqueConstraints, String tableName, List<UniqueConstraintHolder> uniqueConstraints,
String constraints, Table denormalizedSuperclassTable String constraints, Table denormalizedSuperclassTable) {
) { EntityTableObjectNameSource tableNameContext = new EntityTableObjectNameSource( tableName, name );
String logicalName = StringHelper.isNotEmpty( tableName ) ? EntityTableNamingStrategyHelper namingStrategyHelper = new EntityTableNamingStrategyHelper( name );
tableName : final Table table = TableBinder.buildAndFillTable(
StringHelper.unqualify( name ); schema,
Table table = TableBinder.fillTable( catalog,
schema, catalog, tableNameContext,
getClassTableName( tableName ), namingStrategyHelper,
logicalName, persistentClass.isAbstract(),
persistentClass.isAbstract(), uniqueConstraints, constraints, uniqueConstraints,
denormalizedSuperclassTable, mappings constraints,
denormalizedSuperclassTable,
mappings
); );
if ( persistentClass instanceof TableOwner ) { if ( persistentClass instanceof TableOwner ) {
@ -592,68 +623,89 @@ public class EntityBinder {
return addJoin( null, joinTable, holder, noDelayInPkColumnCreation ); return addJoin( null, joinTable, holder, noDelayInPkColumnCreation );
} }
/** private static class SecondaryTableNameSource implements ObjectNameSource {
* A non null propertyHolder means than we process the Pk creation without delay // always has an explicit name
*/ private final String explicitName;
private SecondaryTableNameSource(String explicitName) {
this.explicitName = explicitName;
}
public String getExplicitName() {
return explicitName;
}
public String getLogicalName() {
return explicitName;
}
}
private static class SecondaryTableNamingStrategyHelper implements ObjectNameNormalizer.NamingStrategyHelper {
public String determineImplicitName(NamingStrategy strategy) {
// todo : throw an error?
return null;
}
public String handleExplicitName(NamingStrategy strategy, String name) {
return strategy.tableName( name );
}
}
private static SecondaryTableNamingStrategyHelper SEC_TBL_NS_HELPER = new SecondaryTableNamingStrategyHelper();
private Join addJoin( private Join addJoin(
SecondaryTable secondaryTable, JoinTable joinTable, PropertyHolder propertyHolder, SecondaryTable secondaryTable,
boolean noDelayInPkColumnCreation JoinTable joinTable,
) { PropertyHolder propertyHolder,
boolean noDelayInPkColumnCreation) {
// A non null propertyHolder means than we process the Pk creation without delay
Join join = new Join(); Join join = new Join();
join.setPersistentClass( persistentClass ); join.setPersistentClass( persistentClass );
String schema;
String catalog; final String schema;
String table; final String catalog;
String realTable; final SecondaryTableNameSource secondaryTableNameContext;
UniqueConstraint[] uniqueConstraintsAnn; final Object joinColumns;
final List<UniqueConstraintHolder> uniqueConstraintHolders;
if ( secondaryTable != null ) { if ( secondaryTable != null ) {
schema = secondaryTable.schema(); schema = secondaryTable.schema();
catalog = secondaryTable.catalog(); catalog = secondaryTable.catalog();
table = secondaryTable.name(); secondaryTableNameContext = new SecondaryTableNameSource( secondaryTable.name() );
realTable = mappings.getNamingStrategy().tableName( table ); //always an explicit table name joinColumns = secondaryTable.pkJoinColumns();
uniqueConstraintsAnn = secondaryTable.uniqueConstraints(); uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders( secondaryTable.uniqueConstraints() );
} }
else if ( joinTable != null ) { else if ( joinTable != null ) {
schema = joinTable.schema(); schema = joinTable.schema();
catalog = joinTable.catalog(); catalog = joinTable.catalog();
table = joinTable.name(); secondaryTableNameContext = new SecondaryTableNameSource( joinTable.name() );
realTable = mappings.getNamingStrategy().tableName( table ); //always an explicit table name joinColumns = joinTable.joinColumns();
uniqueConstraintsAnn = joinTable.uniqueConstraints(); uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders( joinTable.uniqueConstraints() );
} }
else { else {
throw new AssertionFailure( "Both JoinTable and SecondaryTable are null" ); throw new AssertionFailure( "Both JoinTable and SecondaryTable are null" );
} }
List uniqueConstraints = new ArrayList( uniqueConstraintsAnn == null ?
0 : final Table table = TableBinder.buildAndFillTable(
uniqueConstraintsAnn.length );
if ( uniqueConstraintsAnn != null && uniqueConstraintsAnn.length != 0 ) {
for (UniqueConstraint uc : uniqueConstraintsAnn) {
uniqueConstraints.add( uc.columnNames() );
}
}
Table tableMapping = TableBinder.fillTable(
schema, schema,
catalog, catalog,
realTable, secondaryTableNameContext,
table, false, uniqueConstraints, null, null, mappings SEC_TBL_NS_HELPER,
false,
uniqueConstraintHolders,
null,
null,
mappings
); );
//no check constraints available on joins //no check constraints available on joins
join.setTable( tableMapping ); join.setTable( table );
//somehow keep joins() for later. //somehow keep joins() for later.
//Has to do the work later because it needs persistentClass id! //Has to do the work later because it needs persistentClass id!
Object joinColumns = null;
//get the appropriate pk columns
if ( secondaryTable != null ) {
joinColumns = secondaryTable.pkJoinColumns();
}
else if ( joinTable != null ) {
joinColumns = joinTable.joinColumns();
}
log.info( log.info(
"Adding secondary table to entity {} -> {}", persistentClass.getEntityName(), join.getTable().getName() "Adding secondary table to entity {} -> {}", persistentClass.getEntityName(), join.getTable().getName()
); );
org.hibernate.annotations.Table matchingTable = findMatchingComplimentTableAnnotation( join ); org.hibernate.annotations.Table matchingTable = findMatchingComplimentTableAnnotation( join );
if ( matchingTable != null ) { if ( matchingTable != null ) {
join.setSequentialSelect( FetchMode.JOIN != matchingTable.fetch() ); join.setSequentialSelect( FetchMode.JOIN != matchingTable.fetch() );
@ -689,8 +741,8 @@ public class EntityBinder {
createPrimaryColumnsToSecondaryTable( joinColumns, propertyHolder, join ); createPrimaryColumnsToSecondaryTable( joinColumns, propertyHolder, join );
} }
else { else {
secondaryTables.put( realTable, join ); secondaryTables.put( table.getQuotedName(), join );
secondaryTableJoins.put( realTable, joinColumns ); secondaryTableJoins.put( table.getQuotedName(), joinColumns );
} }
return join; return join;
} }

View File

@ -32,10 +32,15 @@ import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.annotations.Index; import org.hibernate.annotations.Index;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.cfg.BinderHelper; import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.Ejb3JoinColumn; import org.hibernate.cfg.Ejb3JoinColumn;
import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.IndexOrUniqueKeySecondPass; import org.hibernate.cfg.IndexOrUniqueKeySecondPass;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.cfg.ObjectNameSource;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.UniqueConstraintHolder;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.DependantValue;
@ -62,7 +67,8 @@ public class TableBinder {
private String catalog; private String catalog;
private String name; private String name;
private boolean isAbstract; private boolean isAbstract;
private List<String[]> uniqueConstraints; private List<UniqueConstraintHolder> uniqueConstraints;
// private List<String[]> uniqueConstraints;
String constraints; String constraints;
Table denormalizedSuperTable; Table denormalizedSuperTable;
ExtendedMappings mappings; ExtendedMappings mappings;
@ -93,7 +99,7 @@ public class TableBinder {
} }
public void setUniqueConstraints(UniqueConstraint[] uniqueConstraints) { public void setUniqueConstraints(UniqueConstraint[] uniqueConstraints) {
this.uniqueConstraints = TableBinder.buildUniqueConstraints( uniqueConstraints ); this.uniqueConstraints = TableBinder.buildUniqueConstraintHolders( uniqueConstraints );
} }
public void setConstraints(String constraints) { public void setConstraints(String constraints) {
@ -108,45 +114,150 @@ public class TableBinder {
this.mappings = mappings; this.mappings = mappings;
} }
private static class AssociationTableNameSource implements ObjectNameSource {
private final String explicitName;
private final String logicalName;
private AssociationTableNameSource(String explicitName, String logicalName) {
this.explicitName = explicitName;
this.logicalName = logicalName;
}
public String getExplicitName() {
return explicitName;
}
public String getLogicalName() {
return logicalName;
}
}
// only bind association table currently // only bind association table currently
public Table bind() { public Table bind() {
//logicalName only accurate for assoc table... //logicalName only accurate for assoc table...
String unquotedOwnerTable = StringHelper.unquote( ownerEntityTable ); final String unquotedOwnerTable = StringHelper.unquote( ownerEntityTable );
String unquotedAssocTable = StringHelper.unquote( associatedEntityTable ); final String unquotedAssocTable = StringHelper.unquote( associatedEntityTable );
String logicalName = mappings.getNamingStrategy() final ObjectNameSource nameSource = buildNameContext( unquotedOwnerTable, unquotedAssocTable );
.logicalCollectionTableName(
name, final boolean ownerEntityTableQuoted = StringHelper.isQuoted( ownerEntityTable );
final boolean associatedEntityTableQuoted = StringHelper.isQuoted( associatedEntityTable );
final ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper = new ObjectNameNormalizer.NamingStrategyHelper() {
public String determineImplicitName(NamingStrategy strategy) {
final String strategyResult = strategy.collectionTableName(
ownerEntity,
unquotedOwnerTable, unquotedOwnerTable,
associatedEntity,
unquotedAssocTable, unquotedAssocTable,
propertyName ); propertyName
if ( StringHelper.isQuoted( ownerEntityTable ) || StringHelper.isQuoted( associatedEntityTable ) ) {
logicalName = StringHelper.quote( logicalName ); );
} return ownerEntityTableQuoted || associatedEntityTableQuoted
String extendedName; ? StringHelper.quote( strategyResult )
if ( name != null ) { : strategyResult;
extendedName = mappings.getNamingStrategy().tableName( name );
}
else {
extendedName = mappings.getNamingStrategy()
.collectionTableName(
ownerEntity,
unquotedOwnerTable,
associatedEntity,
unquotedAssocTable,
propertyName
);
if ( StringHelper.isQuoted( ownerEntityTable ) || StringHelper.isQuoted( associatedEntityTable ) ) {
extendedName = StringHelper.quote( extendedName );
} }
}
return fillTable( public String handleExplicitName(NamingStrategy strategy, String name) {
schema, catalog, return strategy.tableName( name );
extendedName, logicalName, isAbstract, uniqueConstraints, constraints, }
denormalizedSuperTable, mappings };
return buildAndFillTable(
schema,
catalog,
nameSource,
namingStrategyHelper,
isAbstract,
uniqueConstraints,
constraints,
denormalizedSuperTable,
mappings
); );
} }
private ObjectNameSource buildNameContext(String unquotedOwnerTable, String unquotedAssocTable) {
String logicalName = mappings.getNamingStrategy().logicalCollectionTableName(
name,
unquotedOwnerTable,
unquotedAssocTable,
propertyName
);
if ( StringHelper.isQuoted( ownerEntityTable ) || StringHelper.isQuoted( associatedEntityTable ) ) {
logicalName = StringHelper.quote( logicalName );
}
return new AssociationTableNameSource( name, logicalName );
}
public static Table buildAndFillTable(
String schema,
String catalog,
ObjectNameSource nameSource,
ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper,
boolean isAbstract,
List<UniqueConstraintHolder> uniqueConstraints,
String constraints,
Table denormalizedSuperTable,
ExtendedMappings mappings) {
schema = BinderHelper.isDefault( schema ) ? mappings.getSchemaName() : schema;
catalog = BinderHelper.isDefault( catalog ) ? mappings.getCatalogName() : catalog;
String realTableName = mappings.getObjectNameNormalizer().normalizeDatabaseIdentifier(
nameSource.getExplicitName(),
namingStrategyHelper
);
final Table table;
if ( denormalizedSuperTable != null ) {
table = mappings.addDenormalizedTable(
schema,
catalog,
realTableName,
isAbstract,
null, // subselect
denormalizedSuperTable
);
}
else {
table = mappings.addTable(
schema,
catalog,
realTableName,
null, // subselect
isAbstract
);
}
if ( uniqueConstraints != null && uniqueConstraints.size() > 0 ) {
mappings.addUniqueConstraintHolders( table, uniqueConstraints );
}
if ( constraints != null ) table.addCheckConstraint( constraints );
// logicalName is null if we are in the second pass
final String logicalName = nameSource.getLogicalName();
if ( logicalName != null ) {
mappings.addTableBinding( schema, catalog, logicalName, realTableName, denormalizedSuperTable );
}
return table;
}
/**
*
* @param schema
* @param catalog
* @param realTableName
* @param logicalName
* @param isAbstract
* @param uniqueConstraints
* @param constraints
* @param denormalizedSuperTable
* @param mappings
* @return
*
* @deprecated Use {@link #buildAndFillTable} instead.
*/
@SuppressWarnings({ "JavaDoc" })
public static Table fillTable( public static Table fillTable(
String schema, String catalog, String realTableName, String logicalName, boolean isAbstract, String schema, String catalog, String realTableName, String logicalName, boolean isAbstract,
List uniqueConstraints, String constraints, Table denormalizedSuperTable, ExtendedMappings mappings List uniqueConstraints, String constraints, Table denormalizedSuperTable, ExtendedMappings mappings
@ -195,8 +306,9 @@ public class TableBinder {
associatedClass = destinationEntity; associatedClass = destinationEntity;
} }
else { else {
associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder() associatedClass = columns[0].getPropertyHolder() == null
.getPersistentClass(); ? null
: columns[0].getPropertyHolder().getPersistentClass();
} }
final String mappedByProperty = columns[0].getMappedBy(); final String mappedByProperty = columns[0].getMappedBy();
if ( StringHelper.isNotEmpty( mappedByProperty ) ) { if ( StringHelper.isNotEmpty( mappedByProperty ) ) {
@ -235,7 +347,7 @@ public class TableBinder {
*/ */
Iterator idColumns; Iterator idColumns;
if ( referencedEntity instanceof JoinedSubclass ) { if ( referencedEntity instanceof JoinedSubclass ) {
idColumns = ( (JoinedSubclass) referencedEntity ).getKey().getColumnIterator(); idColumns = referencedEntity.getKey().getColumnIterator();
} }
else { else {
idColumns = referencedEntity.getIdentifier().getColumnIterator(); idColumns = referencedEntity.getIdentifier().getColumnIterator();
@ -345,7 +457,7 @@ public class TableBinder {
} }
} }
value.createForeignKey(); value.createForeignKey();
if ( unique == true ) { if ( unique ) {
createUniqueConstraint( value ); createUniqueConstraint( value );
} }
} }
@ -384,6 +496,10 @@ public class TableBinder {
} }
} }
/**
* @deprecated Use {@link #buildUniqueConstraintHolders} instead
*/
@SuppressWarnings({ "JavaDoc" })
public static List<String[]> buildUniqueConstraints(UniqueConstraint[] constraintsArray) { public static List<String[]> buildUniqueConstraints(UniqueConstraint[] constraintsArray) {
List<String[]> result = new ArrayList<String[]>(); List<String[]> result = new ArrayList<String[]>();
if ( constraintsArray.length != 0 ) { if ( constraintsArray.length != 0 ) {
@ -394,6 +510,32 @@ public class TableBinder {
return result; return result;
} }
/**
* Build a list of {@link org.hibernate.cfg.UniqueConstraintHolder} instances given a list of
* {@link UniqueConstraint} annotations.
*
* @param annotations The {@link UniqueConstraint} annotations.
*
* @return The built {@link org.hibernate.cfg.UniqueConstraintHolder} instances.
*/
public static List<UniqueConstraintHolder> buildUniqueConstraintHolders(UniqueConstraint[] annotations) {
List<UniqueConstraintHolder> result;
if ( annotations == null || annotations.length == 0 ) {
result = java.util.Collections.emptyList();
}
else {
result = new ArrayList<UniqueConstraintHolder>( CollectionHelper.determineProperSizing( annotations.length ) );
for ( UniqueConstraint uc : annotations ) {
result.add(
new UniqueConstraintHolder()
.setName( uc.name() )
.setColumns( uc.columnNames() )
);
}
}
return result;
}
public void setDefaultName( public void setDefaultName(
String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
String propertyName String propertyName

View File

@ -68,7 +68,6 @@ import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver; import org.hibernate.SessionFactoryObserver;
import org.hibernate.DuplicateMappingException; import org.hibernate.DuplicateMappingException;
import org.hibernate.tuple.entity.EntityTuplizerFactory; import org.hibernate.tuple.entity.EntityTuplizerFactory;
import org.hibernate.tuple.component.ComponentTuplizerFactory;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunction;
@ -2456,6 +2455,8 @@ public class Configuration implements Serializable {
Table table = ( Table ) tables.get( key ); Table table = ( Table ) tables.get( key );
if ( table == null ) { if ( table == null ) {
schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
table = new Table(); table = new Table();
table.setAbstract( isAbstract ); table.setAbstract( isAbstract );
table.setName( name ); table.setName( name );
@ -2485,6 +2486,9 @@ public class Configuration implements Serializable {
throw new DuplicateMappingException( "table", name ); throw new DuplicateMappingException( "table", name );
} }
schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
Table table = new DenormalizedTable( includedTable ); Table table = new DenormalizedTable( includedTable );
table.setAbstract( isAbstract ); table.setAbstract( isAbstract );
table.setName( name ); table.setName( name );
@ -2786,5 +2790,22 @@ public class Configuration implements Serializable {
public MappedSuperclass getMappedSuperclass(Class type) { public MappedSuperclass getMappedSuperclass(Class type) {
return (MappedSuperclass) mappedSuperclasses.get( type ); return (MappedSuperclass) mappedSuperclasses.get( type );
} }
public ObjectNameNormalizer getObjectNameNormalizer() {
return normalizer;
}
}
final ObjectNameNormalizer normalizer = new ObjectNameNormalizerImpl();
final class ObjectNameNormalizerImpl extends ObjectNameNormalizer implements Serializable {
public boolean isUseQuotedIdentifiersGlobally() {
String setting = (String) properties.get( Environment.GLOBALLY_QUOTED_IDENTIFIERS );
return setting != null && Boolean.valueOf( setting ).booleanValue();
}
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
} }
} }

View File

@ -501,6 +501,11 @@ public final class Environment {
*/ */
public static final String JACC_CONTEXTID = "hibernate.jacc_context_id"; public static final String JACC_CONTEXTID = "hibernate.jacc_context_id";
/**
* Should all database identifiers be quoted.
*/
public static final String GLOBALLY_QUOTED_IDENTIFIERS = "hibernate.globally_quoted_identifiers";
/** /**
* Enable nullability checking. * Enable nullability checking.
* Raises an exception if a property marked as not-null is null. * Raises an exception if a property marked as not-null is null.

View File

@ -2045,15 +2045,24 @@ public final class HbmBinder {
// GENERATOR // GENERATOR
Element subnode = node.element( "generator" ); Element subnode = node.element( "generator" );
if ( subnode != null ) { if ( subnode != null ) {
model.setIdentifierGeneratorStrategy( subnode.attributeValue( "class" ) ); final String generatorClass = subnode.attributeValue( "class" );
model.setIdentifierGeneratorStrategy( generatorClass );
Properties params = new Properties(); Properties params = new Properties();
// YUCK! but cannot think of a clean way to do this given the string-config based scheme
params.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, mappings.getObjectNameNormalizer() );
if ( mappings.getSchemaName() != null ) { if ( mappings.getSchemaName() != null ) {
params.setProperty( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() ); params.setProperty(
PersistentIdentifierGenerator.SCHEMA,
mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( mappings.getSchemaName() )
);
} }
if ( mappings.getCatalogName() != null ) { if ( mappings.getCatalogName() != null ) {
params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() ); params.setProperty(
PersistentIdentifierGenerator.CATALOG,
mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( mappings.getCatalogName() )
);
} }
Iterator iter = subnode.elementIterator( "param" ); Iterator iter = subnode.elementIterator( "param" );

View File

@ -543,4 +543,11 @@ public interface Mappings {
* @return the MappedSuperclass * @return the MappedSuperclass
*/ */
org.hibernate.mapping.MappedSuperclass getMappedSuperclass(Class type); org.hibernate.mapping.MappedSuperclass getMappedSuperclass(Class type);
/**
* Retrieve the database identifier normalizer for this context.
*
* @return The normalizer.
*/
public ObjectNameNormalizer getObjectNameNormalizer();
} }

View File

@ -0,0 +1,132 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.cfg;
import org.hibernate.util.StringHelper;
/**
* Provides centralized normalization of how database object names are handled.
*
* @author Steve Ebersole
*/
public abstract class ObjectNameNormalizer {
/**
* Helper contract for dealing with {@link NamingStrategy} in different situations.
*/
public static interface NamingStrategyHelper {
/**
* Called when the user supplied no explicit name/identifier for the given database object.
*
* @param strategy The naming strategy in effect
*
* @return The implicit name
*/
public String determineImplicitName(NamingStrategy strategy);
/**
* Called when the user has supplied an explicit name for the database object.
*
* @param strategy The naming strategy in effect
* @param name The {@link ObjectNameNormalizer#normalizeIdentifierQuoting normalized} explicit object name.
*
* @return The strategy-handled name.
*/
public String handleExplicitName(NamingStrategy strategy, String name);
}
/**
* Performs the actual contract of normalizing a database name.
*
* @param explicitName The name the user explicitly gave for the database object.
* @param helper The {@link NamingStrategy} helper.
*
* @return The normalized identifier.
*/
public String normalizeDatabaseIdentifier(final String explicitName, NamingStrategyHelper helper) {
// apply naming strategy
if ( StringHelper.isEmpty( explicitName ) ) {
// No explicit name given, so allow the naming strategy the chance
// to determine it based on the corresponding mapped java name
final String objectName = helper.determineImplicitName( getNamingStrategy() );
// Conceivable that the naming strategy could return a quoted identifier, or
// that user enabled <delimited-identifiers/>
return normalizeIdentifierQuoting( objectName );
}
else {
// An explicit name was given:
// in some cases we allow the naming strategy to "fine tune" these, but first
// handle any quoting for consistent handling in naming strategies
String objectName = normalizeIdentifierQuoting( explicitName );
objectName = helper.handleExplicitName( getNamingStrategy(), objectName );
return normalizeIdentifierQuoting( objectName );
}
}
/**
* Allow normalizing of just the quoting aspect of identifiers. This is useful for
* schema and catalog in terms of initially making this public.
* <p/>
* This implements the rules set forth in JPA 2 (section "2.13 Naming of Database Objects") which
* states that the double-quote (") is the character which should be used to denote a <tt>quoted
* identifier</tt>. Here, we handle recognizing that and converting it to the more elegant
* bactick (`) approach used in Hibernate.. Additionally we account for applying what JPA2 terms
*
*
* @param identifier The identifier to be quoting-normalized.
* @return The identifier accounting for any quoting that need be applied.
*/
public String normalizeIdentifierQuoting(String identifier) {
if ( identifier == null ) {
return null;
}
// Convert the JPA2 specific quoting character (double quote) to Hibernate's (back tick)
if ( identifier.startsWith( "\"" ) && identifier.endsWith( "\"" ) ) {
return '`' + identifier.substring( 1, identifier.length() - 1 ) + '`';
}
// If the user has requested "global" use of quoted identifiers, quote this identifier (using back ticks)
// if not already
if ( isUseQuotedIdentifiersGlobally() && ! ( identifier.startsWith( "`" ) && identifier.endsWith( "`" ) ) ) {
return '`' + identifier + '`';
}
return identifier;
}
/**
* Retrieve whether the user requested that all database identifiers be quoted.
*
* @return True if the user requested that all database identifiers be quoted, false otherwise.
*/
protected abstract boolean isUseQuotedIdentifiersGlobally();
/**
* Get the current {@link NamingStrategy}.
*
* @return The current {@link NamingStrategy}.
*/
protected abstract NamingStrategy getNamingStrategy();
}

View File

@ -0,0 +1,46 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.cfg;
/**
* Source for database object names (identifiers).
*
* @author Steve Ebersole
*/
public interface ObjectNameSource {
/**
* Retrieve the name explicitly provided by the user.
*
* @return The explicit name.
*/
public String getExplicitName();
/**
* Retrieve the logical name for this object. Usually this is the name under which
* the "thing" is registered with the {@link Mappings}.
*
* @return The logical name.
*/
public String getLogicalName();
}

View File

@ -169,6 +169,11 @@ public class DerbyDialect extends DB2Dialect {
return sb.toString(); return sb.toString();
} }
public boolean supportsVariableLimit() {
// we bind the limit and offset values directly into the sql...
return false;
}
private boolean hasForUpdateClause(int forUpdateIndex) { private boolean hasForUpdateClause(int forUpdateIndex) {
return forUpdateIndex >= 0; return forUpdateIndex >= 0;
} }

View File

@ -1466,17 +1466,21 @@ qu *
* By default, the incoming value is checked to see if its first character * By default, the incoming value is checked to see if its first character
* is the back-tick (`). If so, the dialect specific quoting is applied. * is the back-tick (`). If so, the dialect specific quoting is applied.
* *
* @param column The value to be quoted. * @param name The value to be quoted.
* @return The quoted (or unmodified, if not starting with back-tick) value. * @return The quoted (or unmodified, if not starting with back-tick) value.
* @see #openQuote() * @see #openQuote()
* @see #closeQuote() * @see #closeQuote()
*/ */
public final String quote(String column) { public final String quote(String name) {
if ( column.charAt( 0 ) == '`' ) { if ( name == null ) {
return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote(); return null;
}
if ( name.charAt( 0 ) == '`' ) {
return openQuote() + name.substring( 1, name.length() - 1 ) + closeQuote();
} }
else { else {
return column; return name;
} }
} }

View File

@ -34,6 +34,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.exception.JDBCExceptionHelper;
@ -61,38 +62,55 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
private String sql; private String sql;
private Class returnClass; private Class returnClass;
public synchronized Serializable generate(SessionImplementor session, Object object) public synchronized Serializable generate(SessionImplementor session, Object object) throws HibernateException {
throws HibernateException { if ( sql != null ) {
if (sql!=null) {
getNext( session ); getNext( session );
} }
return IdentifierGeneratorHelper.createNumber(next++, returnClass); return IdentifierGeneratorHelper.createNumber( next++, returnClass );
} }
public void configure(Type type, Properties params, Dialect dialect) public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
throws MappingException {
String tableList = params.getProperty("tables");
if (tableList==null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES);
String[] tables = StringHelper.split(", ", tableList);
String column = params.getProperty("column");
if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG);
returnClass = type.getReturnedClass(); returnClass = type.getReturnedClass();
ObjectNameNormalizer normalizer =
( ObjectNameNormalizer ) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );
String column = params.getProperty( "column" );
if ( column == null ) {
column = params.getProperty( PersistentIdentifierGenerator.PK );
}
column = dialect.quote( normalizer.normalizeIdentifierQuoting( column ) );
String tableList = params.getProperty( "tables" );
if ( tableList == null ) {
tableList = params.getProperty( PersistentIdentifierGenerator.TABLES );
}
String[] tables = StringHelper.split( ", ", tableList );
final String schema = dialect.quote(
normalizer.normalizeIdentifierQuoting(
params.getProperty( PersistentIdentifierGenerator.SCHEMA )
)
);
final String catalog = dialect.quote(
normalizer.normalizeIdentifierQuoting(
params.getProperty( PersistentIdentifierGenerator.CATALOG )
)
);
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for ( int i=0; i<tables.length; i++ ) { for ( int i=0; i < tables.length; i++ ) {
if (tables.length>1) { final String tableName = dialect.quote( normalizer.normalizeIdentifierQuoting( tables[i] ) );
buf.append("select ").append(column).append(" from "); if ( tables.length > 1 ) {
buf.append( "select " ).append( column ).append( " from " );
}
buf.append( Table.qualify( catalog, schema, tableName ) );
if ( i < tables.length-1 ) {
buf.append( " union " );
} }
buf.append( Table.qualify( catalog, schema, tables[i] ) );
if ( i<tables.length-1) buf.append(" union ");
} }
if (tables.length>1) { if ( tables.length > 1 ) {
buf.insert(0, "( ").append(" ) ids_"); buf.insert( 0, "( " ).append( " ) ids_" );
column = "ids_." + column; column = "ids_." + column;
} }
@ -100,9 +118,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
} }
private void getNext( SessionImplementor session ) { private void getNext( SessionImplementor session ) {
log.debug( "fetching initial value: " + sql );
log.debug("fetching initial value: " + sql);
try { try {
PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
try { try {
@ -133,7 +149,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
sqle, sqle,
"could not fetch initial value for increment generator", "could not fetch initial value for increment generator",
sql sql
); );
} }
} }

View File

@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.jdbc.util.FormatStyle; import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
@ -221,22 +222,41 @@ public class MultipleHiLoPerTableGenerator
} }
public void configure(Type type, Properties params, Dialect dialect) throws MappingException { public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
tableName = PropertiesHelper.getString(ID_TABLE, params, DEFAULT_TABLE); ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
pkColumnName = PropertiesHelper.getString(PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN);
valueColumnName = PropertiesHelper.getString(VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN);
String schemaName = params.getProperty(SCHEMA);
String catalogName = params.getProperty(CATALOG);
keySize = PropertiesHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH);
String keyValue = PropertiesHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) );
if ( tableName.indexOf( '.' )<0 ) { tableName = normalizer.normalizeIdentifierQuoting( PropertiesHelper.getString( ID_TABLE, params, DEFAULT_TABLE ) );
if ( tableName.indexOf( '.' ) < 0 ) {
tableName = dialect.quote( tableName );
final String schemaName = dialect.quote(
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
);
final String catalogName = dialect.quote(
normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) )
);
tableName = Table.qualify( catalogName, schemaName, tableName ); tableName = Table.qualify( catalogName, schemaName, tableName );
} }
else {
// if already qualified there is not much we can do in a portable manner so we pass it
// through and assume the user has set up the name correctly.
}
pkColumnName = dialect.quote(
normalizer.normalizeIdentifierQuoting(
PropertiesHelper.getString( PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN )
)
);
valueColumnName = dialect.quote(
normalizer.normalizeIdentifierQuoting(
PropertiesHelper.getString( VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN )
)
);
keySize = PropertiesHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH);
String keyValue = PropertiesHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) );
query = "select " + query = "select " +
valueColumnName + valueColumnName +
" from " + " from " +
dialect.appendLockHint(LockMode.UPGRADE, tableName) + dialect.appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) +
" where " + pkColumnName + " = '" + keyValue + "'" + " where " + pkColumnName + " = '" + keyValue + "'" +
dialect.getForUpdateString(); dialect.getForUpdateString();

View File

@ -68,6 +68,11 @@ public interface PersistentIdentifierGenerator extends IdentifierGenerator {
*/ */
public static final String CATALOG = "catalog"; public static final String CATALOG = "catalog";
/**
* The key under whcih to find the {@link org.hibernate.cfg.ObjectNameNormalizer} in the config param map.
*/
public static final String IDENTIFIER_NORMALIZER = "identifier_normalizer";
/** /**
* The SQL required to create the underlying database objects. * The SQL required to create the underlying database objects.
* *

View File

@ -34,6 +34,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
@ -53,8 +54,8 @@ import org.hibernate.util.PropertiesHelper;
* @see TableHiLoGenerator * @see TableHiLoGenerator
* @author Gavin King * @author Gavin King
*/ */
public class SequenceGenerator implements PersistentIdentifierGenerator, Configurable { public class SequenceGenerator implements PersistentIdentifierGenerator, Configurable {
private static final Logger log = LoggerFactory.getLogger(SequenceGenerator.class);
/** /**
* The sequence parameter * The sequence parameter
@ -72,20 +73,29 @@ public class SequenceGenerator implements PersistentIdentifierGenerator, Configu
private Type identifierType; private Type identifierType;
private String sql; private String sql;
private static final Logger log = LoggerFactory.getLogger(SequenceGenerator.class);
public void configure(Type type, Properties params, Dialect dialect) throws MappingException { public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
sequenceName = PropertiesHelper.getString(SEQUENCE, params, "hibernate_sequence"); ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
parameters = params.getProperty(PARAMETERS); sequenceName = normalizer.normalizeIdentifierQuoting(
String schemaName = params.getProperty(SCHEMA); PropertiesHelper.getString( SEQUENCE, params, "hibernate_sequence" )
String catalogName = params.getProperty(CATALOG); );
parameters = params.getProperty( PARAMETERS );
if (sequenceName.indexOf( '.' ) < 0) { if ( sequenceName.indexOf( '.' ) < 0 ) {
sequenceName = Table.qualify( catalogName, schemaName, sequenceName ); final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) );
final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) );
sequenceName = Table.qualify(
dialect.quote( catalogName ),
dialect.quote( schemaName ),
dialect.quote( sequenceName )
);
}
else {
// if already qualified there is not much we can do in a portable manner so we pass it
// through and assume the user has set up the name correctly.
} }
this.identifierType = type; this.identifierType = type;
sql = dialect.getSequenceNextValString(sequenceName); sql = dialect.getSequenceNextValString( sequenceName );
} }
public Serializable generate(SessionImplementor session, Object obj) public Serializable generate(SessionImplementor session, Object obj)

View File

@ -36,6 +36,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.jdbc.util.FormatStyle; import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
@ -88,20 +89,33 @@ public class TableGenerator extends TransactionHelper
private String update; private String update;
public void configure(Type type, Properties params, Dialect dialect) { public void configure(Type type, Properties params, Dialect dialect) {
ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME); tableName = PropertiesHelper.getString( TABLE, params, DEFAULT_TABLE_NAME );
columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME); if ( tableName.indexOf( '.' ) < 0 ) {
String schemaName = params.getProperty(SCHEMA); final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) );
String catalogName = params.getProperty(CATALOG); final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) );
tableName = Table.qualify(
if ( tableName.indexOf( '.' )<0 ) { dialect.quote( catalogName ),
tableName = Table.qualify( catalogName, schemaName, tableName ); dialect.quote( schemaName ),
dialect.quote( tableName )
);
} }
else {
// if already qualified there is not much we can do in a portable manner so we pass it
// through and assume the user has set up the name correctly.
}
columnName = dialect.quote(
normalizer.normalizeIdentifierQuoting(
PropertiesHelper.getString( COLUMN, params, DEFAULT_COLUMN_NAME )
)
);
query = "select " + query = "select " +
columnName + columnName +
" from " + " from " +
dialect.appendLockHint(LockMode.UPGRADE, tableName) + dialect.appendLockHint(LockMode.PESSIMISTIC_WRITE, tableName) +
dialect.getForUpdateString(); dialect.getForUpdateString();
update = "update " + update = "update " +

View File

@ -34,6 +34,7 @@ import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.Configurable; import org.hibernate.id.Configurable;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionImplementor;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.util.PropertiesHelper; import org.hibernate.util.PropertiesHelper;
@ -160,7 +161,7 @@ public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Co
this.identifierType = type; this.identifierType = type;
boolean forceTableUse = PropertiesHelper.getBoolean( FORCE_TBL_PARAM, params, false ); boolean forceTableUse = PropertiesHelper.getBoolean( FORCE_TBL_PARAM, params, false );
final String sequenceName = determineSequenceName( params ); final String sequenceName = determineSequenceName( params, dialect );
final int initialValue = determineInitialValue( params ); final int initialValue = determineInitialValue( params );
int incrementSize = determineIncrementSize( params ); int incrementSize = determineIncrementSize( params );
@ -190,14 +191,25 @@ public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Co
* Called during {@link #configure configuration}. * Called during {@link #configure configuration}.
* *
* @param params The params supplied in the generator config (plus some standard useful extras). * @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect in effect
* @return The sequence name * @return The sequence name
*/ */
protected String determineSequenceName(Properties params) { protected String determineSequenceName(Properties params, Dialect dialect) {
ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
String sequenceName = PropertiesHelper.getString( SEQUENCE_PARAM, params, DEF_SEQUENCE_NAME ); String sequenceName = PropertiesHelper.getString( SEQUENCE_PARAM, params, DEF_SEQUENCE_NAME );
if ( sequenceName.indexOf( '.' ) < 0 ) { if ( sequenceName.indexOf( '.' ) < 0 ) {
sequenceName = normalizer.normalizeIdentifierQuoting( sequenceName );
String schemaName = params.getProperty( SCHEMA ); String schemaName = params.getProperty( SCHEMA );
String catalogName = params.getProperty( CATALOG ); String catalogName = params.getProperty( CATALOG );
sequenceName = Table.qualify( catalogName, schemaName, sequenceName ); sequenceName = Table.qualify(
dialect.quote( catalogName ),
dialect.quote( schemaName ),
dialect.quote( sequenceName )
);
}
else {
// if already qualified there is not much we can do in a portable manner so we pass it
// through and assume the user has set up the name correctly.
} }
return sequenceName; return sequenceName;
} }
@ -210,10 +222,13 @@ public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Co
* physical table</b>. * physical table</b>.
* *
* @param params The params supplied in the generator config (plus some standard useful extras). * @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect in effect.
* @return The value column name * @return The value column name
*/ */
protected String determineValueColumnName(Properties params) { protected String determineValueColumnName(Properties params, Dialect dialect) {
return PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
String name = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) );
} }
/** /**
@ -296,7 +311,7 @@ public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Co
return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize ); return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize );
} }
else { else {
String valueColumnName = determineValueColumnName( params ); String valueColumnName = determineValueColumnName( params, dialect );
return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize ); return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize );
} }
} }

View File

@ -46,8 +46,8 @@ import org.hibernate.type.Type;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.jdbc.util.FormatStyle; import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.util.PropertiesHelper; import org.hibernate.util.PropertiesHelper;
@ -287,9 +287,9 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
public void configure(Type type, Properties params, Dialect dialect) throws MappingException { public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
identifierType = type; identifierType = type;
tableName = determneGeneratorTableName( params ); tableName = determneGeneratorTableName( params, dialect );
segmentColumnName = determineSegmentColumnName( params ); segmentColumnName = determineSegmentColumnName( params, dialect );
valueColumnName = determineValueColumnName( params ); valueColumnName = determineValueColumnName( params, dialect );
segmentValue = determineSegmentValue( params ); segmentValue = determineSegmentValue( params );
@ -313,16 +313,27 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
* *
* @see #getTableName() * @see #getTableName()
* @param params The params supplied in the generator config (plus some standard useful extras). * @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect in effect
* @return The table name to use. * @return The table name to use.
*/ */
protected String determneGeneratorTableName(Properties params) { protected String determneGeneratorTableName(Properties params, Dialect dialect) {
String name = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE ); String name = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE );
boolean isGivenNameUnqualified = name.indexOf( '.' ) < 0; boolean isGivenNameUnqualified = name.indexOf( '.' ) < 0;
if ( isGivenNameUnqualified ) { if ( isGivenNameUnqualified ) {
ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
name = normalizer.normalizeIdentifierQuoting( name );
// if the given name is un-qualified we may neen to qualify it // if the given name is un-qualified we may neen to qualify it
String schemaName = params.getProperty( SCHEMA ); String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) );
String catalogName = params.getProperty( CATALOG ); String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) );
name = Table.qualify( catalogName, schemaName, name ); name = Table.qualify(
dialect.quote( catalogName ),
dialect.quote( schemaName ),
dialect.quote( name)
);
}
else {
// if already qualified there is not much we can do in a portable manner so we pass it
// through and assume the user has set up the name correctly.
} }
return name; return name;
} }
@ -335,10 +346,13 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
* *
* @see #getSegmentColumnName() * @see #getSegmentColumnName()
* @param params The params supplied in the generator config (plus some standard useful extras). * @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect in effect
* @return The name of the segment column * @return The name of the segment column
*/ */
protected String determineSegmentColumnName(Properties params) { protected String determineSegmentColumnName(Properties params, Dialect dialect) {
return PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN ); ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
String name = PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN );
return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) );
} }
/** /**
@ -348,10 +362,13 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
* *
* @see #getValueColumnName() * @see #getValueColumnName()
* @param params The params supplied in the generator config (plus some standard useful extras). * @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect in effect
* @return The name of the value column * @return The name of the value column
*/ */
protected String determineValueColumnName(Properties params) { protected String determineValueColumnName(Properties params, Dialect dialect) {
return PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
String name = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) );
} }
/** /**

View File

@ -69,7 +69,7 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
this.valueColumnName = valueColumnName; this.valueColumnName = valueColumnName;
selectQuery = "select " + valueColumnName + " as id_val" + selectQuery = "select " + valueColumnName + " as id_val" +
" from " + dialect.appendLockHint( LockMode.UPGRADE, tableName ) + " from " + dialect.appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) +
dialect.getForUpdateString(); dialect.getForUpdateString();
updateQuery = "update " + tableName + updateQuery = "update " + tableName +

View File

@ -11,8 +11,11 @@ import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.SequenceStructure; import org.hibernate.id.enhanced.SequenceStructure;
import org.hibernate.id.enhanced.OptimizerFactory; import org.hibernate.id.enhanced.OptimizerFactory;
import org.hibernate.id.enhanced.TableStructure; import org.hibernate.id.enhanced.TableStructure;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.cfg.NamingStrategy;
/** /**
* Tests that SequenceStyleGenerator configures itself as expected * Tests that SequenceStyleGenerator configures itself as expected
@ -34,7 +37,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
*/ */
public void testDefaultedSequenceBackedConfiguration() { public void testDefaultedSequenceBackedConfiguration() {
Dialect dialect = new SequenceDialect(); Dialect dialect = new SequenceDialect();
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
SequenceStyleGenerator generator = new SequenceStyleGenerator(); SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect ); generator.configure( Hibernate.LONG, props, dialect );
@ -43,12 +46,29 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() ); assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
} }
private Properties buildGeneratorPropertiesBase() {
Properties props = new Properties();
props.put(
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
new ObjectNameNormalizer() {
protected boolean isUseQuotedIdentifiersGlobally() {
return false;
}
protected NamingStrategy getNamingStrategy() {
return null;
}
}
);
return props;
}
/** /**
* Test all params defaulted with a dialect which does not support sequences * Test all params defaulted with a dialect which does not support sequences
*/ */
public void testDefaultedTableBackedConfiguration() { public void testDefaultedTableBackedConfiguration() {
Dialect dialect = new TableDialect(); Dialect dialect = new TableDialect();
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
SequenceStyleGenerator generator = new SequenceStyleGenerator(); SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect ); generator.configure( Hibernate.LONG, props, dialect );
@ -63,7 +83,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
* dialect supporting pooled sequences (pooled) and not (hilo) * dialect supporting pooled sequences (pooled) and not (hilo)
*/ */
public void testDefaultOptimizerBasedOnIncrementBackedBySequence() { public void testDefaultOptimizerBasedOnIncrementBackedBySequence() {
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" ); props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
// for dialects which do not support pooled sequences, we default to pooled+table // for dialects which do not support pooled sequences, we default to pooled+table
@ -89,7 +109,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
* pooled. * pooled.
*/ */
public void testDefaultOptimizerBasedOnIncrementBackedByTable() { public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" ); props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
Dialect dialect = new TableDialect(); Dialect dialect = new TableDialect();
SequenceStyleGenerator generator = new SequenceStyleGenerator(); SequenceStyleGenerator generator = new SequenceStyleGenerator();
@ -104,7 +124,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
*/ */
public void testForceTableUse() { public void testForceTableUse() {
Dialect dialect = new SequenceDialect(); Dialect dialect = new SequenceDialect();
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" ); props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
SequenceStyleGenerator generator = new SequenceStyleGenerator(); SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect ); generator.configure( Hibernate.LONG, props, dialect );
@ -121,7 +141,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
final Dialect dialect = new SequenceDialect(); final Dialect dialect = new SequenceDialect();
// optimizer=none w/ increment > 1 => should honor optimizer // optimizer=none w/ increment > 1 => should honor optimizer
Properties props = new Properties(); Properties props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE ); props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" ); props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
SequenceStyleGenerator generator = new SequenceStyleGenerator(); SequenceStyleGenerator generator = new SequenceStyleGenerator();
@ -132,7 +152,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() ); assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() );
// optimizer=hilo w/ increment > 1 => hilo // optimizer=hilo w/ increment > 1 => hilo
props = new Properties(); props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO ); props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" ); props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
generator = new SequenceStyleGenerator(); generator = new SequenceStyleGenerator();
@ -143,7 +163,7 @@ public class SequenceStyleConfigUnitTest extends UnitTestCase {
assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() ); assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
// optimizer=pooled w/ increment > 1 => hilo // optimizer=pooled w/ increment > 1 => hilo
props = new Properties(); props = buildGeneratorPropertiesBase();
props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL ); props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" ); props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
generator = new SequenceStyleGenerator(); generator = new SequenceStyleGenerator();