JPA-43 - Impl Index and ForeignKey for JPA 2.1
This commit is contained in:
parent
ed549f5793
commit
3335710a38
|
@ -2172,7 +2172,6 @@ public final class AnnotationBinder {
|
||||||
JoinColumn[] annInverseJoins;
|
JoinColumn[] annInverseJoins;
|
||||||
JoinTable assocTable = propertyHolder.getJoinTable( property );
|
JoinTable assocTable = propertyHolder.getJoinTable( property );
|
||||||
CollectionTable collectionTable = property.getAnnotation( CollectionTable.class );
|
CollectionTable collectionTable = property.getAnnotation( CollectionTable.class );
|
||||||
|
|
||||||
if ( assocTable != null || collectionTable != null ) {
|
if ( assocTable != null || collectionTable != null ) {
|
||||||
|
|
||||||
final String catalog;
|
final String catalog;
|
||||||
|
@ -2181,6 +2180,8 @@ public final class AnnotationBinder {
|
||||||
final UniqueConstraint[] uniqueConstraints;
|
final UniqueConstraint[] uniqueConstraints;
|
||||||
final JoinColumn[] joins;
|
final JoinColumn[] joins;
|
||||||
final JoinColumn[] inverseJoins;
|
final JoinColumn[] inverseJoins;
|
||||||
|
final javax.persistence.Index[] jpaIndexes;
|
||||||
|
|
||||||
|
|
||||||
//JPA 2 has priority
|
//JPA 2 has priority
|
||||||
if ( collectionTable != null ) {
|
if ( collectionTable != null ) {
|
||||||
|
@ -2190,6 +2191,7 @@ public final class AnnotationBinder {
|
||||||
uniqueConstraints = collectionTable.uniqueConstraints();
|
uniqueConstraints = collectionTable.uniqueConstraints();
|
||||||
joins = collectionTable.joinColumns();
|
joins = collectionTable.joinColumns();
|
||||||
inverseJoins = null;
|
inverseJoins = null;
|
||||||
|
jpaIndexes = collectionTable.indexes();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
catalog = assocTable.catalog();
|
catalog = assocTable.catalog();
|
||||||
|
@ -2198,10 +2200,13 @@ public final class AnnotationBinder {
|
||||||
uniqueConstraints = assocTable.uniqueConstraints();
|
uniqueConstraints = assocTable.uniqueConstraints();
|
||||||
joins = assocTable.joinColumns();
|
joins = assocTable.joinColumns();
|
||||||
inverseJoins = assocTable.inverseJoinColumns();
|
inverseJoins = assocTable.inverseJoinColumns();
|
||||||
|
jpaIndexes = assocTable.indexes();
|
||||||
}
|
}
|
||||||
|
|
||||||
collectionBinder.setExplicitAssociationTable( true );
|
collectionBinder.setExplicitAssociationTable( true );
|
||||||
|
if ( jpaIndexes != null && jpaIndexes.length > 0 ) {
|
||||||
|
associationTableBinder.setJpaIndex( jpaIndexes );
|
||||||
|
}
|
||||||
if ( !BinderHelper.isEmptyAnnotationValue( schema ) ) {
|
if ( !BinderHelper.isEmptyAnnotationValue( schema ) ) {
|
||||||
associationTableBinder.setSchema( schema );
|
associationTableBinder.setSchema( schema );
|
||||||
}
|
}
|
||||||
|
@ -2212,7 +2217,7 @@ public final class AnnotationBinder {
|
||||||
associationTableBinder.setName( tableName );
|
associationTableBinder.setName( tableName );
|
||||||
}
|
}
|
||||||
associationTableBinder.setUniqueConstraints( uniqueConstraints );
|
associationTableBinder.setUniqueConstraints( uniqueConstraints );
|
||||||
|
associationTableBinder.setJpaIndex( jpaIndexes );
|
||||||
//set check constaint in the second pass
|
//set check constaint in the second pass
|
||||||
annJoins = joins.length == 0 ? null : joins;
|
annJoins = joins.length == 0 ? null : joins;
|
||||||
annInverseJoins = inverseJoins == null || inverseJoins.length == 0 ? null : inverseJoins;
|
annInverseJoins = inverseJoins == null || inverseJoins.length == 0 ? null : inverseJoins;
|
||||||
|
|
|
@ -251,6 +251,7 @@ public class Configuration implements Serializable {
|
||||||
private Set<String> defaultNamedGenerators;
|
private Set<String> defaultNamedGenerators;
|
||||||
private Map<String, Properties> generatorTables;
|
private Map<String, Properties> generatorTables;
|
||||||
private Map<Table, List<UniqueConstraintHolder>> uniqueConstraintHoldersByTable;
|
private Map<Table, List<UniqueConstraintHolder>> uniqueConstraintHoldersByTable;
|
||||||
|
private Map<Table, List<JPAIndexHolder>> jpaIndexHoldersByTable;
|
||||||
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;
|
||||||
|
@ -324,6 +325,7 @@ public class Configuration implements Serializable {
|
||||||
defaultSqlResultSetMappingNames = new HashSet<String>();
|
defaultSqlResultSetMappingNames = new HashSet<String>();
|
||||||
defaultNamedGenerators = new HashSet<String>();
|
defaultNamedGenerators = new HashSet<String>();
|
||||||
uniqueConstraintHoldersByTable = new HashMap<Table, List<UniqueConstraintHolder>>();
|
uniqueConstraintHoldersByTable = new HashMap<Table, List<UniqueConstraintHolder>>();
|
||||||
|
jpaIndexHoldersByTable = new HashMap<Table,List<JPAIndexHolder>>( );
|
||||||
mappedByResolver = new HashMap<String, String>();
|
mappedByResolver = new HashMap<String, String>();
|
||||||
propertyRefResolver = new HashMap<String, String>();
|
propertyRefResolver = new HashMap<String, String>();
|
||||||
caches = new ArrayList<CacheHolder>();
|
caches = new ArrayList<CacheHolder>();
|
||||||
|
@ -1380,6 +1382,17 @@ public class Configuration implements Serializable {
|
||||||
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
|
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(Table table : jpaIndexHoldersByTable.keySet()){
|
||||||
|
final List<JPAIndexHolder> jpaIndexHolders = jpaIndexHoldersByTable.get( table );
|
||||||
|
int uniqueIndexPerTable = 0;
|
||||||
|
for ( JPAIndexHolder holder : jpaIndexHolders ) {
|
||||||
|
uniqueIndexPerTable++;
|
||||||
|
final String keyName = StringHelper.isEmpty( holder.getName() )
|
||||||
|
? "idx_"+table.getName()+"_" + uniqueIndexPerTable
|
||||||
|
: holder.getName();
|
||||||
|
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns(), holder.getOrdering(), holder.isUnique() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSecondPassesOfType(Class<? extends SecondPass> type) {
|
private void processSecondPassesOfType(Class<? extends SecondPass> type) {
|
||||||
|
@ -1533,7 +1546,11 @@ public class Configuration implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames) {
|
private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames){
|
||||||
|
buildUniqueKeyFromColumnNames( table, keyName, columnNames, null, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames, String[] orderings, boolean unique) {
|
||||||
keyName = normalizer.normalizeIdentifierQuoting( keyName );
|
keyName = normalizer.normalizeIdentifierQuoting( keyName );
|
||||||
|
|
||||||
int size = columnNames.length;
|
int size = columnNames.length;
|
||||||
|
@ -1553,13 +1570,29 @@ public class Configuration implements Serializable {
|
||||||
unboundNoLogical.add( new Column( logicalColumnName ) );
|
unboundNoLogical.add( new Column( logicalColumnName ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UniqueKey uk = table.getOrCreateUniqueKey( keyName );
|
if ( unique ) {
|
||||||
for ( Column column : columns ) {
|
UniqueKey uk = table.getOrCreateUniqueKey( keyName );
|
||||||
if ( table.containsColumn( column ) ) {
|
for ( int i = 0; i < columns.length; i++ ) {
|
||||||
uk.addColumn( column );
|
Column column = columns[i];
|
||||||
unbound.remove( column );
|
String order = orderings != null ? orderings[i] : null;
|
||||||
|
if ( table.containsColumn( column ) ) {
|
||||||
|
uk.addColumn( column, order );
|
||||||
|
unbound.remove( column );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Index index = table.getOrCreateIndex( keyName );
|
||||||
|
for ( int i = 0; i < columns.length; i++ ) {
|
||||||
|
Column column = columns[i];
|
||||||
|
String order = orderings != null ? orderings[i] : null;
|
||||||
|
if ( table.containsColumn( column ) ) {
|
||||||
|
index.addColumn( column, order );
|
||||||
|
unbound.remove( column );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
||||||
StringBuilder sb = new StringBuilder( "Unable to create unique key constraint (" );
|
StringBuilder sb = new StringBuilder( "Unable to create unique key constraint (" );
|
||||||
for ( String columnName : columnNames ) {
|
for ( String columnName : columnNames ) {
|
||||||
|
@ -3309,6 +3342,15 @@ public class Configuration implements Serializable {
|
||||||
holderList.addAll( uniqueConstraintHolders );
|
holderList.addAll( uniqueConstraintHolders );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addJpaIndexHolders(Table table, List<JPAIndexHolder> holders) {
|
||||||
|
List<JPAIndexHolder> holderList = jpaIndexHoldersByTable.get( table );
|
||||||
|
if ( holderList == null ) {
|
||||||
|
holderList = new ArrayList<JPAIndexHolder>();
|
||||||
|
jpaIndexHoldersByTable.put( table, holderList );
|
||||||
|
}
|
||||||
|
holderList.addAll( holders );
|
||||||
|
}
|
||||||
|
|
||||||
public void addMappedBy(String entityName, String propertyName, String inversePropertyName) {
|
public void addMappedBy(String entityName, String propertyName, String inversePropertyName) {
|
||||||
mappedByResolver.put( entityName + "." + propertyName, inversePropertyName );
|
mappedByResolver.put( entityName + "." + propertyName, inversePropertyName );
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ public class IndexOrUniqueKeySecondPass implements SecondPass {
|
||||||
private Table table;
|
private Table table;
|
||||||
private final String indexName;
|
private final String indexName;
|
||||||
private final String[] columns;
|
private final String[] columns;
|
||||||
private final String[] ordering;
|
|
||||||
private final Mappings mappings;
|
private final Mappings mappings;
|
||||||
private final Ejb3Column column;
|
private final Ejb3Column column;
|
||||||
private final boolean unique;
|
private final boolean unique;
|
||||||
|
@ -54,46 +53,10 @@ public class IndexOrUniqueKeySecondPass implements SecondPass {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
this.indexName = indexName;
|
this.indexName = indexName;
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
this.ordering = null;
|
|
||||||
this.mappings = mappings;
|
this.mappings = mappings;
|
||||||
this.column = null;
|
this.column = null;
|
||||||
this.unique = false;
|
this.unique = false;
|
||||||
}
|
}
|
||||||
//used for the new JPA 2.1 @Index
|
|
||||||
public IndexOrUniqueKeySecondPass(Table table, String indexName, String columnList, Mappings mappings, boolean unique) {
|
|
||||||
this.table = table;
|
|
||||||
StringTokenizer tokenizer = new StringTokenizer( columnList, "," );
|
|
||||||
List<String> tmp = new ArrayList<String>();
|
|
||||||
while ( tokenizer.hasMoreElements() ) {
|
|
||||||
tmp.add( tokenizer.nextToken().trim() );
|
|
||||||
}
|
|
||||||
this.indexName = StringHelper.isNotEmpty( indexName ) ? indexName : "IDX_" + table.uniqueColumnString( tmp.iterator() );
|
|
||||||
this.columns = new String[tmp.size()];
|
|
||||||
this.ordering = new String[tmp.size()];
|
|
||||||
initializeColumns(columns, ordering, tmp);
|
|
||||||
this.mappings = mappings;
|
|
||||||
this.column = null;
|
|
||||||
this.unique = unique;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeColumns(String[] columns, String[] ordering, List<String> list) {
|
|
||||||
for ( int i = 0, size = list.size(); i < size; i++ ) {
|
|
||||||
final String description = list.get( i );
|
|
||||||
final String tmp = description.toLowerCase();
|
|
||||||
if ( tmp.endsWith( " desc" ) ) {
|
|
||||||
columns[i] = description.substring( 0, description.length() - 5 );
|
|
||||||
ordering[i] = "desc";
|
|
||||||
}
|
|
||||||
else if ( tmp.endsWith( " asc" ) ) {
|
|
||||||
columns[i] = description.substring( 0, description.length() - 4 );
|
|
||||||
ordering[i] = "asc";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
columns[i] = description;
|
|
||||||
ordering[i] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,23 +75,21 @@ public class IndexOrUniqueKeySecondPass implements SecondPass {
|
||||||
this.columns = null;
|
this.columns = null;
|
||||||
this.mappings = mappings;
|
this.mappings = mappings;
|
||||||
this.unique = unique;
|
this.unique = unique;
|
||||||
this.ordering = null;
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void doSecondPass(Map persistentClasses) throws MappingException {
|
public void doSecondPass(Map persistentClasses) throws MappingException {
|
||||||
if ( columns != null ) {
|
if ( columns != null ) {
|
||||||
for ( int i = 0; i < columns.length; i++ ) {
|
for ( int i = 0; i < columns.length; i++ ) {
|
||||||
final String order = ordering != null ? ordering[i] : null;
|
addConstraintToColumn( columns[i] );
|
||||||
addConstraintToColumn( columns[i], order );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( column != null ) {
|
if ( column != null ) {
|
||||||
this.table = column.getTable();
|
this.table = column.getTable();
|
||||||
addConstraintToColumn( mappings.getLogicalColumnName( column.getMappingColumn().getQuotedName(), table ), null );
|
addConstraintToColumn( mappings.getLogicalColumnName( column.getMappingColumn().getQuotedName(), table ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConstraintToColumn(final String columnName, final String ordering) {
|
private void addConstraintToColumn(final String columnName ) {
|
||||||
Column column = table.getColumn(
|
Column column = table.getColumn(
|
||||||
new Column(
|
new Column(
|
||||||
mappings.getPhysicalColumnName( columnName, table )
|
mappings.getPhysicalColumnName( columnName, table )
|
||||||
|
@ -140,8 +101,8 @@ public class IndexOrUniqueKeySecondPass implements SecondPass {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( unique )
|
if ( unique )
|
||||||
table.getOrCreateUniqueKey( indexName ).addColumn( column, ordering );
|
table.getOrCreateUniqueKey( indexName ).addColumn( column );
|
||||||
else
|
else
|
||||||
table.getOrCreateIndex( indexName ).addColumn( column, ordering );
|
table.getOrCreateIndex( indexName ).addColumn( column );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.cfg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import javax.persistence.Index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu <stliu@hibernate.org>
|
||||||
|
*/
|
||||||
|
public class JPAIndexHolder {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String[] columns;
|
||||||
|
private final String[] ordering;
|
||||||
|
private final boolean unique;
|
||||||
|
|
||||||
|
public JPAIndexHolder(Index index) {
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer( index.columnList(), "," );
|
||||||
|
List<String> tmp = new ArrayList<String>();
|
||||||
|
while ( tokenizer.hasMoreElements() ) {
|
||||||
|
tmp.add( tokenizer.nextToken().trim() );
|
||||||
|
}
|
||||||
|
this.name = index.name();
|
||||||
|
this.columns = new String[tmp.size()];
|
||||||
|
this.ordering = new String[tmp.size()];
|
||||||
|
this.unique = index.unique();
|
||||||
|
initializeColumns( columns, ordering, tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getColumns() {
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getOrdering() {
|
||||||
|
return ordering;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnique() {
|
||||||
|
return unique;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeColumns(String[] columns, String[] ordering, List<String> list) {
|
||||||
|
for ( int i = 0, size = list.size(); i < size; i++ ) {
|
||||||
|
final String description = list.get( i );
|
||||||
|
final String tmp = description.toLowerCase();
|
||||||
|
if ( tmp.endsWith( " desc" ) ) {
|
||||||
|
columns[i] = description.substring( 0, description.length() - 5 );
|
||||||
|
ordering[i] = "desc";
|
||||||
|
}
|
||||||
|
else if ( tmp.endsWith( " asc" ) ) {
|
||||||
|
columns[i] = description.substring( 0, description.length() - 4 );
|
||||||
|
ordering[i] = "asc";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
columns[i] = description;
|
||||||
|
ordering[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -721,6 +721,8 @@ public interface Mappings {
|
||||||
|
|
||||||
public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder> uniqueConstraintHolders);
|
public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder> uniqueConstraintHolders);
|
||||||
|
|
||||||
|
public void addJpaIndexHolders(Table table, List<JPAIndexHolder> jpaIndexHolders);
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -23,10 +23,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cfg.annotations;
|
package org.hibernate.cfg.annotations;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.OrderBy;
|
import org.hibernate.annotations.OrderBy;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
|
||||||
|
@ -36,7 +33,6 @@ import org.hibernate.mapping.PersistentClass;
|
||||||
* @author Matthew Inger
|
* @author Matthew Inger
|
||||||
*/
|
*/
|
||||||
public class SetBinder extends CollectionBinder {
|
public class SetBinder extends CollectionBinder {
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SetBinder.class.getName());
|
|
||||||
|
|
||||||
public SetBinder() {
|
public SetBinder() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.annotations.Index;
|
||||||
import org.hibernate.cfg.BinderHelper;
|
import org.hibernate.cfg.BinderHelper;
|
||||||
import org.hibernate.cfg.Ejb3JoinColumn;
|
import org.hibernate.cfg.Ejb3JoinColumn;
|
||||||
import org.hibernate.cfg.IndexOrUniqueKeySecondPass;
|
import org.hibernate.cfg.IndexOrUniqueKeySecondPass;
|
||||||
|
import org.hibernate.cfg.JPAIndexHolder;
|
||||||
import org.hibernate.cfg.Mappings;
|
import org.hibernate.cfg.Mappings;
|
||||||
import org.hibernate.cfg.NamingStrategy;
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||||
|
@ -80,6 +81,7 @@ public class TableBinder {
|
||||||
private String ownerEntity;
|
private String ownerEntity;
|
||||||
private String associatedEntity;
|
private String associatedEntity;
|
||||||
private boolean isJPA2ElementCollection;
|
private boolean isJPA2ElementCollection;
|
||||||
|
private List<JPAIndexHolder> jpaIndexHolders;
|
||||||
|
|
||||||
public void setSchema(String schema) {
|
public void setSchema(String schema) {
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
|
@ -105,6 +107,10 @@ public class TableBinder {
|
||||||
this.uniqueConstraints = TableBinder.buildUniqueConstraintHolders( uniqueConstraints );
|
this.uniqueConstraints = TableBinder.buildUniqueConstraintHolders( uniqueConstraints );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setJpaIndex(javax.persistence.Index[] jpaIndex){
|
||||||
|
this.jpaIndexHolders = buildJpaIndexHolder( jpaIndex );
|
||||||
|
}
|
||||||
|
|
||||||
public void setConstraints(String constraints) {
|
public void setConstraints(String constraints) {
|
||||||
this.constraints = constraints;
|
this.constraints = constraints;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +189,7 @@ public class TableBinder {
|
||||||
namingStrategyHelper,
|
namingStrategyHelper,
|
||||||
isAbstract,
|
isAbstract,
|
||||||
uniqueConstraints,
|
uniqueConstraints,
|
||||||
|
jpaIndexHolders,
|
||||||
constraints,
|
constraints,
|
||||||
denormalizedSuperTable,
|
denormalizedSuperTable,
|
||||||
mappings,
|
mappings,
|
||||||
|
@ -190,6 +197,7 @@ public class TableBinder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ObjectNameSource buildNameContext(String unquotedOwnerTable, String unquotedAssocTable) {
|
private ObjectNameSource buildNameContext(String unquotedOwnerTable, String unquotedAssocTable) {
|
||||||
String logicalName = mappings.getNamingStrategy().logicalCollectionTableName(
|
String logicalName = mappings.getNamingStrategy().logicalCollectionTableName(
|
||||||
name,
|
name,
|
||||||
|
@ -211,10 +219,11 @@ public class TableBinder {
|
||||||
ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper,
|
ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper,
|
||||||
boolean isAbstract,
|
boolean isAbstract,
|
||||||
List<UniqueConstraintHolder> uniqueConstraints,
|
List<UniqueConstraintHolder> uniqueConstraints,
|
||||||
|
List<JPAIndexHolder> jpaIndexHolders,
|
||||||
String constraints,
|
String constraints,
|
||||||
Table denormalizedSuperTable,
|
Table denormalizedSuperTable,
|
||||||
Mappings mappings,
|
Mappings mappings,
|
||||||
String subselect) {
|
String subselect){
|
||||||
schema = BinderHelper.isEmptyAnnotationValue( schema ) ? mappings.getSchemaName() : schema;
|
schema = BinderHelper.isEmptyAnnotationValue( schema ) ? mappings.getSchemaName() : schema;
|
||||||
catalog = BinderHelper.isEmptyAnnotationValue( catalog ) ? mappings.getCatalogName() : catalog;
|
catalog = BinderHelper.isEmptyAnnotationValue( catalog ) ? mappings.getCatalogName() : catalog;
|
||||||
|
|
||||||
|
@ -244,10 +253,14 @@ public class TableBinder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( uniqueConstraints != null && uniqueConstraints.size() > 0 ) {
|
if ( CollectionHelper.isNotEmpty( uniqueConstraints ) ) {
|
||||||
mappings.addUniqueConstraintHolders( table, uniqueConstraints );
|
mappings.addUniqueConstraintHolders( table, uniqueConstraints );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( jpaIndexHolders ) ) {
|
||||||
|
mappings.addJpaIndexHolders( table, jpaIndexHolders );
|
||||||
|
}
|
||||||
|
|
||||||
if ( constraints != null ) table.addCheckConstraint( constraints );
|
if ( constraints != null ) table.addCheckConstraint( constraints );
|
||||||
|
|
||||||
// logicalName is null if we are in the second pass
|
// logicalName is null if we are in the second pass
|
||||||
|
@ -258,6 +271,23 @@ public class TableBinder {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Table buildAndFillTable(
|
||||||
|
String schema,
|
||||||
|
String catalog,
|
||||||
|
ObjectNameSource nameSource,
|
||||||
|
ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper,
|
||||||
|
boolean isAbstract,
|
||||||
|
List<UniqueConstraintHolder> uniqueConstraints,
|
||||||
|
String constraints,
|
||||||
|
Table denormalizedSuperTable,
|
||||||
|
Mappings mappings,
|
||||||
|
String subselect) {
|
||||||
|
return buildAndFillTable( schema, catalog, nameSource, namingStrategyHelper, isAbstract, uniqueConstraints, null, constraints
|
||||||
|
, denormalizedSuperTable, mappings, subselect);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #buildAndFillTable} instead.
|
* @deprecated Use {@link #buildAndFillTable} instead.
|
||||||
*/
|
*/
|
||||||
|
@ -515,18 +545,15 @@ public class TableBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addIndexes(Table hibTable, javax.persistence.Index[] indexes, Mappings mappings) {
|
public static void addIndexes(Table hibTable, javax.persistence.Index[] indexes, Mappings mappings) {
|
||||||
for ( javax.persistence.Index index : indexes ) {
|
mappings.addJpaIndexHolders( hibTable, buildJpaIndexHolder( indexes ) );
|
||||||
//no need to handle inSecondPass here since it is only called from EntityBinder
|
}
|
||||||
mappings.addSecondPass(
|
|
||||||
new IndexOrUniqueKeySecondPass(
|
public static List<JPAIndexHolder> buildJpaIndexHolder(javax.persistence.Index[] indexes){
|
||||||
hibTable,
|
List<JPAIndexHolder> holders = new ArrayList<JPAIndexHolder>( indexes.length );
|
||||||
index.name(),
|
for(javax.persistence.Index index : indexes){
|
||||||
index.columnList(),
|
holders.add( new JPAIndexHolder( index ) );
|
||||||
mappings,
|
|
||||||
index.unique()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return holders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Set;
|
||||||
import javax.persistence.CollectionTable;
|
import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Index;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class WealthyPerson extends Person {
|
public class WealthyPerson extends Person {
|
||||||
|
@ -15,6 +16,6 @@ public class WealthyPerson extends Person {
|
||||||
protected Set<Address> legacyVacationHomes = new HashSet<Address>();
|
protected Set<Address> legacyVacationHomes = new HashSet<Address>();
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@CollectionTable(name = "WelPers_VacHomes")
|
@CollectionTable(name = "WelPers_VacHomes", indexes = @Index( columnList = "countryName, type_id"))
|
||||||
protected Set<Address> explicitVacationHomes = new HashSet<Address>();
|
protected Set<Address> explicitVacationHomes = new HashSet<Address>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,24 @@ import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.mapping.Bag;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Index;
|
import org.hibernate.mapping.Index;
|
||||||
import org.hibernate.mapping.Join;
|
import org.hibernate.mapping.Join;
|
||||||
|
import org.hibernate.mapping.List;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.Set;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.UniqueKey;
|
import org.hibernate.mapping.UniqueKey;
|
||||||
|
import org.hibernate.mapping.Value;
|
||||||
|
import org.hibernate.test.annotations.embedded.Address;
|
||||||
|
import org.hibernate.test.annotations.embedded.AddressType;
|
||||||
import org.hibernate.test.annotations.embedded.Book;
|
import org.hibernate.test.annotations.embedded.Book;
|
||||||
|
import org.hibernate.test.annotations.embedded.Person;
|
||||||
import org.hibernate.test.annotations.embedded.Summary;
|
import org.hibernate.test.annotations.embedded.Summary;
|
||||||
|
import org.hibernate.test.annotations.embedded.WealthyPerson;
|
||||||
|
import org.hibernate.test.event.collection.detached.*;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,11 +56,20 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
public class IndexTest extends BaseCoreFunctionalTestCase {
|
public class IndexTest extends BaseCoreFunctionalTestCase {
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] { Car.class, Book.class, Summary.class };
|
return new Class[] { Car.class,
|
||||||
|
Book.class,
|
||||||
|
Summary.class,
|
||||||
|
WealthyPerson.class,
|
||||||
|
Person.class,
|
||||||
|
AddressType.class,
|
||||||
|
Address.class,
|
||||||
|
Alias.class,
|
||||||
|
org.hibernate.test.event.collection.detached.Character.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicIndex() {
|
public void testTableIndex() {
|
||||||
PersistentClass entity = configuration().getClassMapping( Car.class.getName() );
|
PersistentClass entity = configuration().getClassMapping( Car.class.getName() );
|
||||||
Iterator itr = entity.getTable().getUniqueKeyIterator();
|
Iterator itr = entity.getTable().getUniqueKeyIterator();
|
||||||
assertTrue( itr.hasNext() );
|
assertTrue( itr.hasNext() );
|
||||||
|
@ -94,4 +114,50 @@ public class IndexTest extends BaseCoreFunctionalTestCase {
|
||||||
assertSame( join.getTable(), index.getTable() );
|
assertSame( join.getTable(), index.getTable() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCollectionTableIndex(){
|
||||||
|
PersistentClass entity = configuration().getClassMapping( WealthyPerson.class.getName() );
|
||||||
|
Property property = entity.getProperty( "explicitVacationHomes" );
|
||||||
|
Set set = (Set)property.getValue();
|
||||||
|
Table collectionTable = set.getCollectionTable();
|
||||||
|
|
||||||
|
Iterator<Index> itr = collectionTable.getIndexIterator();
|
||||||
|
assertTrue( itr.hasNext() );
|
||||||
|
Index index = itr.next();
|
||||||
|
assertFalse( itr.hasNext() );
|
||||||
|
assertTrue( "index name is not generated", StringHelper.isNotEmpty( index.getName() ) );
|
||||||
|
assertEquals( 2, index.getColumnSpan() );
|
||||||
|
Iterator<Column> columnIterator = index.getColumnIterator();
|
||||||
|
Column column = columnIterator.next();
|
||||||
|
assertEquals( "countryName", column.getName() );
|
||||||
|
column = columnIterator.next();
|
||||||
|
assertEquals( "type_id", column.getName() );
|
||||||
|
assertSame( collectionTable, index.getTable() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJoinTableIndex(){
|
||||||
|
PersistentClass entity = configuration().getClassMapping( Alias.class.getName() );
|
||||||
|
Property property = entity.getProperty( "characters" );
|
||||||
|
Bag set = (Bag)property.getValue();
|
||||||
|
Table collectionTable = set.getCollectionTable();
|
||||||
|
|
||||||
|
Iterator<UniqueKey> itr = collectionTable.getUniqueKeyIterator();
|
||||||
|
assertTrue( itr.hasNext() );
|
||||||
|
UniqueKey index = itr.next();
|
||||||
|
assertFalse( itr.hasNext() );
|
||||||
|
assertTrue( "index name is not generated", StringHelper.isNotEmpty( index.getName() ) );
|
||||||
|
assertEquals( 1, index.getColumnSpan() );
|
||||||
|
Iterator<Column> columnIterator = index.getColumnIterator();
|
||||||
|
Column column = columnIterator.next();
|
||||||
|
assertEquals( "characters_id", column.getName() );
|
||||||
|
assertSame( collectionTable, index.getTable() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTableGeneratorIndex(){
|
||||||
|
//todo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.test.event.collection.detached;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Index;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToMany;
|
import javax.persistence.ManyToMany;
|
||||||
|
@ -68,7 +69,7 @@ public class Alias implements Identifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManyToMany( cascade = CascadeType.ALL )
|
@ManyToMany( cascade = CascadeType.ALL )
|
||||||
@JoinTable( name = "CHARACTER_ALIAS" )
|
@JoinTable( name = "CHARACTER_ALIAS", indexes = @Index( columnList = "characters_id", unique = true))
|
||||||
// @JoinTable(
|
// @JoinTable(
|
||||||
// name = "CHARACTER_ALIAS",
|
// name = "CHARACTER_ALIAS",
|
||||||
// joinColumns = @JoinColumn(name="ALIAS_ID", referencedColumnName="ID"),
|
// joinColumns = @JoinColumn(name="ALIAS_ID", referencedColumnName="ID"),
|
||||||
|
|
Loading…
Reference in New Issue