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:
parent
ecb103cf55
commit
a2bf14ae7c
|
@ -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 );
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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" );
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 " +
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 +
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue