mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-07 11:48:18 +00:00
HHH-6287 bind @Table.uniqueConstraints
This commit is contained in:
parent
ddc1bccee6
commit
0eb87b73b9
@ -24,6 +24,8 @@
|
|||||||
package org.hibernate.metamodel.relational;
|
package org.hibernate.metamodel.relational;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -34,26 +36,32 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractTableSpecification implements TableSpecification, ValueContainer {
|
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 PrimaryKey primaryKey = new PrimaryKey( this );
|
||||||
private List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
|
private List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<SimpleValue> values() {
|
public Iterable<SimpleValue> values() {
|
||||||
return values;
|
return values.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 );
|
final Column column = new Column( this, values.size(), name );
|
||||||
values.add( column );
|
values.put(name, column );
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 );
|
final DerivedValue value = new DerivedValue( this, values.size(), fragment );
|
||||||
values.add( value );
|
values.put(fragment, value );
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -39,8 +40,8 @@ public class Table extends AbstractTableSpecification implements ValueContainer,
|
|||||||
private final Identifier tableName;
|
private final Identifier tableName;
|
||||||
private final String qualifiedName;
|
private final String qualifiedName;
|
||||||
|
|
||||||
private List<Index> indexes;
|
private LinkedHashMap<String,Index> indexes;
|
||||||
private List<UniqueKey> uniqueKeys;
|
private LinkedHashMap<String,UniqueKey> uniqueKeys;
|
||||||
private List<String> checkConstraints;
|
private List<String> checkConstraints;
|
||||||
private Set<String> comments;
|
private Set<String> comments;
|
||||||
|
|
||||||
@ -81,29 +82,35 @@ public String toLoggableString() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Index> getIndexes() {
|
public Iterable<Index> getIndexes() {
|
||||||
return indexes;
|
return indexes.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Index getOrCreateIndex(String name) {
|
public Index getOrCreateIndex(String name) {
|
||||||
|
if(indexes!=null && indexes.containsKey( name )){
|
||||||
|
return indexes.get( name );
|
||||||
|
}
|
||||||
Index index = new Index( this, name );
|
Index index = new Index( this, name );
|
||||||
if ( indexes == null ) {
|
if ( indexes == null ) {
|
||||||
indexes = new ArrayList<Index>();
|
indexes = new LinkedHashMap<String,Index>();
|
||||||
}
|
}
|
||||||
indexes.add( index );
|
indexes.put(name, index );
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<UniqueKey> getUniqueKeys() {
|
public Iterable<UniqueKey> getUniqueKeys() {
|
||||||
return uniqueKeys;
|
return uniqueKeys.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniqueKey getOrCreateUniqueKey(String name) {
|
public UniqueKey getOrCreateUniqueKey(String name) {
|
||||||
|
if(uniqueKeys!=null && uniqueKeys.containsKey( name )){
|
||||||
|
return uniqueKeys.get( name );
|
||||||
|
}
|
||||||
UniqueKey uniqueKey = new UniqueKey( this, name );
|
UniqueKey uniqueKey = new UniqueKey( this, name );
|
||||||
if ( uniqueKeys == null ) {
|
if ( uniqueKeys == null ) {
|
||||||
uniqueKeys = new ArrayList<UniqueKey>();
|
uniqueKeys = new LinkedHashMap<String,UniqueKey>();
|
||||||
}
|
}
|
||||||
uniqueKeys.add( uniqueKey );
|
uniqueKeys.put(name, uniqueKey );
|
||||||
return uniqueKey;
|
return uniqueKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
|
|||||||
*
|
*
|
||||||
* @return The generated column
|
* @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.
|
* 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.
|
* @return The generated value.
|
||||||
*/
|
*/
|
||||||
public DerivedValue createDerivedValue(String fragment);
|
public DerivedValue getOrCreateDerivedValue(String fragment);
|
||||||
|
|
||||||
public Iterable<ForeignKey> getForeignKeys();
|
public Iterable<ForeignKey> getForeignKeys();
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ public static Column createColumn(TableSpecification table,
|
|||||||
if ( columnName == null ) {
|
if ( columnName == null ) {
|
||||||
throw new IllegalArgumentException( "columnName must be non-null." );
|
throw new IllegalArgumentException( "columnName must be non-null." );
|
||||||
}
|
}
|
||||||
Column value = table.createColumn( columnName );
|
Column value = table.getOrCreateColumn( columnName );
|
||||||
value.initialize( state, forceNonNullable, forceUnique );
|
value.initialize( state, forceNonNullable, forceUnique );
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DerivedValue createDerivedValue(TableSpecification table,
|
public static DerivedValue createDerivedValue(TableSpecification table,
|
||||||
DerivedValueRelationalState state) {
|
DerivedValueRelationalState state) {
|
||||||
return table.createDerivedValue( state.getFormula() );
|
return table.getOrCreateDerivedValue( state.getFormula() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleValue createSimpleValue(TableSpecification table,
|
public static SimpleValue createSimpleValue(TableSpecification table,
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
import org.hibernate.metamodel.domain.Hierarchical;
|
import org.hibernate.metamodel.domain.Hierarchical;
|
||||||
import org.hibernate.metamodel.relational.Identifier;
|
import org.hibernate.metamodel.relational.Identifier;
|
||||||
import org.hibernate.metamodel.relational.Schema;
|
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.HibernateDotNames;
|
||||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||||
import org.hibernate.metamodel.source.annotations.entity.state.binding.AttributeBindingStateImpl;
|
import org.hibernate.metamodel.source.annotations.entity.state.binding.AttributeBindingStateImpl;
|
||||||
@ -116,12 +118,49 @@ public void bind() {
|
|||||||
|
|
||||||
// bind all attributes - simple as well as associations
|
// bind all attributes - simple as well as associations
|
||||||
bindAttributes( entityBinding );
|
bindAttributes( entityBinding );
|
||||||
|
bindTableUniqueConstraints( entityBinding );
|
||||||
// last, but not least we initialize and register the new EntityBinding
|
// last, but not least we initialize and register the new EntityBinding
|
||||||
entityBinding.initialize( entityBindingState );
|
entityBinding.initialize( entityBindingState );
|
||||||
meta.addEntity( entityBinding );
|
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) {
|
private void bindInheritance(EntityBinding entityBinding) {
|
||||||
entityBinding.setInheritanceType( configuredClass.getInheritanceType() );
|
entityBinding.setInheritanceType( configuredClass.getInheritanceType() );
|
||||||
switch ( configuredClass.getInheritanceType() ) {
|
switch ( configuredClass.getInheritanceType() ) {
|
||||||
|
@ -64,7 +64,7 @@ public void testBasicMiddleOutBuilding() {
|
|||||||
|
|
||||||
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );
|
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );
|
||||||
|
|
||||||
Column idColumn = table.createColumn( "id" );
|
Column idColumn = table.getOrCreateColumn( "id" );
|
||||||
idColumn.setDatatype( BIGINT );
|
idColumn.setDatatype( BIGINT );
|
||||||
idColumn.setSize( Size.precision( 18, 0 ) );
|
idColumn.setSize( Size.precision( 18, 0 ) );
|
||||||
table.getPrimaryKey().addColumn( idColumn );
|
table.getPrimaryKey().addColumn( idColumn );
|
||||||
|
@ -52,7 +52,7 @@ public void testTableCreation() {
|
|||||||
assertNull( table.getPrimaryKey().getName() );
|
assertNull( table.getPrimaryKey().getName() );
|
||||||
assertFalse( table.values().iterator().hasNext() );
|
assertFalse( table.values().iterator().hasNext() );
|
||||||
|
|
||||||
Column idColumn = table.createColumn( "id" );
|
Column idColumn = table.getOrCreateColumn( "id" );
|
||||||
idColumn.setDatatype( INTEGER );
|
idColumn.setDatatype( INTEGER );
|
||||||
idColumn.setSize( Size.precision( 18, 0 ) );
|
idColumn.setSize( Size.precision( 18, 0 ) );
|
||||||
table.getPrimaryKey().addColumn( idColumn );
|
table.getPrimaryKey().addColumn( idColumn );
|
||||||
@ -60,7 +60,7 @@ public void testTableCreation() {
|
|||||||
assertEquals( "my_table_pk", table.getPrimaryKey().getName() );
|
assertEquals( "my_table_pk", table.getPrimaryKey().getName() );
|
||||||
assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() );
|
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.setDatatype( VARCHAR );
|
||||||
col_1.setSize( Size.length( 512 ) );
|
col_1.setSize( Size.length( 512 ) );
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ public void testBasicForeignKeyDefinition() {
|
|||||||
Schema schema = new Schema( null, null );
|
Schema schema = new Schema( null, null );
|
||||||
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
|
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
|
||||||
|
|
||||||
Column bookId = book.createColumn( "id" );
|
Column bookId = book.getOrCreateColumn( "id" );
|
||||||
bookId.setDatatype( INTEGER );
|
bookId.setDatatype( INTEGER );
|
||||||
bookId.setSize( Size.precision( 18, 0 ) );
|
bookId.setSize( Size.precision( 18, 0 ) );
|
||||||
book.getPrimaryKey().addColumn( bookId );
|
book.getPrimaryKey().addColumn( bookId );
|
||||||
@ -98,13 +98,13 @@ public void testBasicForeignKeyDefinition() {
|
|||||||
|
|
||||||
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
|
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
|
||||||
|
|
||||||
Column pageId = page.createColumn( "id" );
|
Column pageId = page.getOrCreateColumn( "id" );
|
||||||
pageId.setDatatype( INTEGER );
|
pageId.setDatatype( INTEGER );
|
||||||
pageId.setSize( Size.precision( 18, 0 ) );
|
pageId.setSize( Size.precision( 18, 0 ) );
|
||||||
page.getPrimaryKey().addColumn( pageId );
|
page.getPrimaryKey().addColumn( pageId );
|
||||||
page.getPrimaryKey().setName( "PAGE_PK" );
|
page.getPrimaryKey().setName( "PAGE_PK" );
|
||||||
|
|
||||||
Column pageBookId = page.createColumn( "BOOK_ID" );
|
Column pageBookId = page.getOrCreateColumn( "BOOK_ID" );
|
||||||
pageId.setDatatype( INTEGER );
|
pageId.setDatatype( INTEGER );
|
||||||
pageId.setSize( Size.precision( 18, 0 ) );
|
pageId.setSize( Size.precision( 18, 0 ) );
|
||||||
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );
|
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* 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
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user