HHH-6287 bind @Table.uniqueConstraints

This commit is contained in:
Strong Liu 2011-06-15 16:18:52 +08:00 committed by Hardy Ferentschik
parent ddc1bccee6
commit 0eb87b73b9
9 changed files with 161 additions and 26 deletions

View File

@ -24,6 +24,8 @@
package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -34,26 +36,32 @@ import java.util.List;
* @author Steve Ebersole
*/
public abstract class AbstractTableSpecification implements TableSpecification, ValueContainer {
private final LinkedHashSet<SimpleValue> values = new LinkedHashSet<SimpleValue>();
private final LinkedHashMap<String,SimpleValue> values = new LinkedHashMap<String,SimpleValue>();
private PrimaryKey primaryKey = new PrimaryKey( this );
private List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
@Override
public Iterable<SimpleValue> values() {
return values;
return values.values();
}
@Override
public Column createColumn(String name) {
public Column getOrCreateColumn(String name) {
if(values.containsKey( name )){
return (Column) values.get( name );
}
final Column column = new Column( this, values.size(), name );
values.add( column );
values.put(name, column );
return column;
}
@Override
public DerivedValue createDerivedValue(String fragment) {
public DerivedValue getOrCreateDerivedValue(String fragment) {
if(values.containsKey( fragment )){
return (DerivedValue) values.get( fragment );
}
final DerivedValue value = new DerivedValue( this, values.size(), fragment );
values.add( value );
values.put(fragment, value );
return value;
}

View File

@ -25,6 +25,7 @@ package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
@ -39,8 +40,8 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
private final Identifier tableName;
private final String qualifiedName;
private List<Index> indexes;
private List<UniqueKey> uniqueKeys;
private LinkedHashMap<String,Index> indexes;
private LinkedHashMap<String,UniqueKey> uniqueKeys;
private List<String> checkConstraints;
private Set<String> comments;
@ -81,29 +82,35 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
@Override
public Iterable<Index> getIndexes() {
return indexes;
return indexes.values();
}
public Index getOrCreateIndex(String name) {
if(indexes!=null && indexes.containsKey( name )){
return indexes.get( name );
}
Index index = new Index( this, name );
if ( indexes == null ) {
indexes = new ArrayList<Index>();
indexes = new LinkedHashMap<String,Index>();
}
indexes.add( index );
indexes.put(name, index );
return index;
}
@Override
public Iterable<UniqueKey> getUniqueKeys() {
return uniqueKeys;
return uniqueKeys.values();
}
public UniqueKey getOrCreateUniqueKey(String name) {
if(uniqueKeys!=null && uniqueKeys.containsKey( name )){
return uniqueKeys.get( name );
}
UniqueKey uniqueKey = new UniqueKey( this, name );
if ( uniqueKeys == null ) {
uniqueKeys = new ArrayList<UniqueKey>();
uniqueKeys = new LinkedHashMap<String,UniqueKey>();
}
uniqueKeys.add( uniqueKey );
uniqueKeys.put(name, uniqueKey );
return uniqueKey;
}

View File

@ -50,7 +50,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
*
* @return The generated column
*/
public Column createColumn(String name);
public Column getOrCreateColumn(String name);
/**
* Factory method for creating a {@link Column} associated with this container.
@ -68,7 +68,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
*
* @return The generated value.
*/
public DerivedValue createDerivedValue(String fragment);
public DerivedValue getOrCreateDerivedValue(String fragment);
public Iterable<ForeignKey> getForeignKeys();

View File

@ -54,14 +54,14 @@ public class ValueCreator {
if ( columnName == null ) {
throw new IllegalArgumentException( "columnName must be non-null." );
}
Column value = table.createColumn( columnName );
Column value = table.getOrCreateColumn( columnName );
value.initialize( state, forceNonNullable, forceUnique );
return value;
}
public static DerivedValue createDerivedValue(TableSpecification table,
DerivedValueRelationalState state) {
return table.createDerivedValue( state.getFormula() );
return table.getOrCreateDerivedValue( state.getFormula() );
}
public static SimpleValue createSimpleValue(TableSpecification table,

View File

@ -57,6 +57,8 @@ import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.Hierarchical;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.UniqueKey;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.entity.state.binding.AttributeBindingStateImpl;
@ -116,12 +118,49 @@ public class EntityBinder {
// bind all attributes - simple as well as associations
bindAttributes( entityBinding );
bindTableUniqueConstraints( entityBinding );
// last, but not least we initialize and register the new EntityBinding
entityBinding.initialize( entityBindingState );
meta.addEntity( entityBinding );
}
private void bindTableUniqueConstraints(EntityBinding entityBinding) {
AnnotationInstance tableAnnotation = JandexHelper.getSingleAnnotation(
configuredClass.getClassInfo(),
JPADotNames.TABLE
);
if ( tableAnnotation == null ) {
return;
}
TableSpecification table = entityBinding.getBaseTable();
bindUniqueConstraints( tableAnnotation, table );
}
/**
* Bind {@link javax.persistence.UniqueConstraint} to table as a {@link UniqueKey}
*
* @param tableAnnotation JPA annotations which has a {@code uniqueConstraints} attribute.
* @param table Table which the UniqueKey bind to.
*/
private void bindUniqueConstraints(AnnotationInstance tableAnnotation,TableSpecification table) {
AnnotationValue value = tableAnnotation.value( "uniqueConstraints" );
if ( value == null ) {
return;
}
AnnotationInstance[] uniqueConstraints = value.asNestedArray();
for ( AnnotationInstance unique : uniqueConstraints ) {
String name = unique.value( "name" ).asString();
UniqueKey uniqueKey = table.getOrCreateUniqueKey( name );
String[] columnNames = unique.value( "columnNames" ).asStringArray();
if ( columnNames.length == 0 ) {
//todo throw exception?
}
for ( String columnName : columnNames ) {
uniqueKey.addColumn( table.getOrCreateColumn( columnName ) );
}
}
}
private void bindInheritance(EntityBinding entityBinding) {
entityBinding.setInheritanceType( configuredClass.getInheritanceType() );
switch ( configuredClass.getInheritanceType() ) {

View File

@ -64,7 +64,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase {
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );
Column idColumn = table.createColumn( "id" );
Column idColumn = table.getOrCreateColumn( "id" );
idColumn.setDatatype( BIGINT );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );

View File

@ -52,7 +52,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertNull( table.getPrimaryKey().getName() );
assertFalse( table.values().iterator().hasNext() );
Column idColumn = table.createColumn( "id" );
Column idColumn = table.getOrCreateColumn( "id" );
idColumn.setDatatype( INTEGER );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
@ -60,7 +60,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertEquals( "my_table_pk", table.getPrimaryKey().getName() );
assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() );
Column col_1 = table.createColumn( "col_1" );
Column col_1 = table.getOrCreateColumn( "col_1" );
col_1.setDatatype( VARCHAR );
col_1.setSize( Size.length( 512 ) );
@ -90,7 +90,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
Schema schema = new Schema( null, null );
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
Column bookId = book.createColumn( "id" );
Column bookId = book.getOrCreateColumn( "id" );
bookId.setDatatype( INTEGER );
bookId.setSize( Size.precision( 18, 0 ) );
book.getPrimaryKey().addColumn( bookId );
@ -98,13 +98,13 @@ public class TableManipulationTests extends BaseUnitTestCase {
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
Column pageId = page.createColumn( "id" );
Column pageId = page.getOrCreateColumn( "id" );
pageId.setDatatype( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
page.getPrimaryKey().addColumn( pageId );
page.getPrimaryKey().setName( "PAGE_PK" );
Column pageBookId = page.createColumn( "BOOK_ID" );
Column pageBookId = page.getOrCreateColumn( "BOOK_ID" );
pageId.setDatatype( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );

View File

@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.annotations.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.junit.Test;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.UniqueKey;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
/**
* test for {@link javax.persistence.UniqueConstraint}
*
* @author Strong Liu
*/
public class UniqueConstraintBindingTests extends BaseAnnotationBindingTestCase {
@Test
public void testTableUniqueconstraints() {
buildMetadataSources( TableWithUniqueConstraint.class );
EntityBinding binding = getEntityBinding( TableWithUniqueConstraint.class );
TableSpecification table = binding.getBaseTable();
Iterable<UniqueKey> uniqueKeyIterable = table.getUniqueKeys();
assertNotNull( uniqueKeyIterable );
int i = 0;
for ( UniqueKey key : uniqueKeyIterable ) {
i++;
assertEquals( "u1", key.getName() );
assertTrue( table == key.getTable() );
assertNotNull( key.getColumns() );
int j = 0;
for ( Column column : key.getColumns() ) {
j++;
}
assertEquals( 2, j );
}
assertEquals( 1, i );
}
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(name = "u1", columnNames = { "name", "age" }) })
class TableWithUniqueConstraint {
@Id
int id;
String name;
int age;
}
}