ANN-856 implement @MapKeyColumn

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17173 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2009-07-21 02:07:50 +00:00
parent 1cac641632
commit 20d22941c0
10 changed files with 120 additions and 20 deletions

View File

@ -73,6 +73,7 @@ import javax.persistence.Version;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
import javax.persistence.CollectionTable; import javax.persistence.CollectionTable;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.persistence.MapKeyColumn;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -132,6 +133,8 @@ import org.hibernate.cfg.annotations.PropertyBinder;
import org.hibernate.cfg.annotations.QueryBinder; import org.hibernate.cfg.annotations.QueryBinder;
import org.hibernate.cfg.annotations.SimpleValueBinder; import org.hibernate.cfg.annotations.SimpleValueBinder;
import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.annotations.TableBinder;
import org.hibernate.cfg.annotations.MapKeyColumnDelegator;
import org.hibernate.cfg.annotations.CustomizableColumns;
import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.Versioning; import org.hibernate.engine.Versioning;
import org.hibernate.id.MultipleHiLoPerTableGenerator; import org.hibernate.id.MultipleHiLoPerTableGenerator;
@ -1538,14 +1541,20 @@ public final class AnnotationBinder {
); );
} }
org.hibernate.annotations.MapKey hibMapKeyAnn = property.getAnnotation( Column[] keyColumns = null;
org.hibernate.annotations.MapKey.class //JPA 2 has priority
); if ( property.isAnnotationPresent( MapKeyColumn.class ) ) {
keyColumns = new Column[] { new MapKeyColumnDelegator( property.getAnnotation( MapKeyColumn.class ) ) };
}
else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) {
keyColumns = property.getAnnotation( org.hibernate.annotations.MapKey.class ).columns();
}
//nullify empty array
keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns : null;
PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData, "mapkey" ); PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData, "mapkey" );
Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation( Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
hibMapKeyAnn != null && hibMapKeyAnn.columns().length > 0 ? keyColumns,
hibMapKeyAnn.columns() :
null,
null, null,
Nullability.FORCED_NOT_NULL, Nullability.FORCED_NOT_NULL,
propertyHolder, propertyHolder,

View File

@ -39,6 +39,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.MapKey; import javax.persistence.MapKey;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
import javax.persistence.MapKeyColumn;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -337,9 +338,11 @@ public abstract class CollectionBinder {
collection.setRole( StringHelper.qualify( propertyHolder.getPath(), propertyName ) ); collection.setRole( StringHelper.qualify( propertyHolder.getPath(), propertyName ) );
collection.setNodeName( propertyName ); collection.setNodeName( propertyName );
if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) && mapKeyPropertyName != null ) { if ( (property.isAnnotationPresent( org.hibernate.annotations.MapKey.class )
|| property.isAnnotationPresent( MapKeyColumn.class ) )
&& mapKeyPropertyName != null ) {
throw new AnnotationException( throw new AnnotationException(
"Cannot mix @javax.persistence.MapKey and @org.hibernate.annotations.MapKey " "Cannot mix @javax.persistence.MapKey and @MapKeyColumn or @org.hibernate.annotations.MapKey "
+ "on the same collection: " + StringHelper.qualify( + "on the same collection: " + StringHelper.qualify(
propertyHolder.getPath(), propertyName propertyHolder.getPath(), propertyName
) )

View File

@ -0,0 +1,27 @@
package org.hibernate.cfg.annotations;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import javax.persistence.Column;
import org.hibernate.annotations.Columns;
/**
* @author Emmanuel Bernard
*/
@SuppressWarnings({ "ClassExplicitlyAnnotation" })
public class CustomizableColumns implements Columns {
private final Column[] columns;
public CustomizableColumns(Column[] columns) {
this.columns = columns;
}
public Column[] columns() {
return columns;
}
public Class<? extends Annotation> annotationType() {
return Columns.class;
}
}

View File

@ -138,13 +138,14 @@ public class MapBinder extends CollectionBinder {
Class target = void.class; Class target = void.class;
/* /*
* target has priority over reflection for the map key type * target has priority over reflection for the map key type
* JPA 2 has priority
*/ */
if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) { if ( property.isAnnotationPresent( MapKeyClass.class ) ) {
target = property.getAnnotation( org.hibernate.annotations.MapKey.class ).targetElement();
}
else if ( property.isAnnotationPresent( MapKeyClass.class ) ) {
target = property.getAnnotation( MapKeyClass.class ).value(); target = property.getAnnotation( MapKeyClass.class ).value();
} }
else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) {
target = property.getAnnotation( org.hibernate.annotations.MapKey.class ).targetElement();
}
else if ( property.isAnnotationPresent( MapKeyManyToMany.class ) ) { else if ( property.isAnnotationPresent( MapKeyManyToMany.class ) ) {
target = property.getAnnotation( MapKeyManyToMany.class ).targetEntity(); target = property.getAnnotation( MapKeyManyToMany.class ).targetEntity();
} }

View File

@ -0,0 +1,61 @@
package org.hibernate.cfg.annotations;
import java.lang.annotation.Annotation;
import javax.persistence.Column;
import javax.persistence.MapKeyColumn;
/**
* @author Emmanuel Bernard
*/
@SuppressWarnings({ "ClassExplicitlyAnnotation" })
public class MapKeyColumnDelegator implements Column {
private final MapKeyColumn column;
public MapKeyColumnDelegator(MapKeyColumn column) {
this.column = column;
}
public String name() {
return column.name();
}
public boolean unique() {
return column.unique();
}
public boolean nullable() {
return column.nullable();
}
public boolean insertable() {
return column.insertable();
}
public boolean updatable() {
return column.updatable();
}
public String columnDefinition() {
return column.columnDefinition();
}
public String table() {
return column.table();
}
public int length() {
return column.length();
}
public int precision() {
return column.precision();
}
public int scale() {
return column.scale();
}
public Class<? extends Annotation> annotationType() {
return Column.class;
}
}

View File

@ -61,7 +61,7 @@ public class PropertyMap {
name = "map_properties", name = "map_properties",
joinColumns = @JoinColumn( name = "map_id" ), joinColumns = @JoinColumn( name = "map_id" ),
inverseJoinColumns = @JoinColumn( name = "property_id" ) ) inverseJoinColumns = @JoinColumn( name = "property_id" ) )
@MapKey( columns = { @Column( name = "map_key" ) } ) @MapKey( columns = { @Column( name = "map_key" ) } ) //keep for legacy test
public Map<String, Property> getProperties() { public Map<String, Property> getProperties() {
return properties; return properties;
} }

View File

@ -8,6 +8,7 @@ import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import javax.persistence.MapKeyColumn;
import org.hibernate.annotations.Fetch; import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.FetchMode;
@ -33,7 +34,7 @@ public class LocalizedString implements Serializable {
new HashMap<String, String>( 1 ); new HashMap<String, String>( 1 );
@ElementCollection @ElementCollection
@MapKey( columns = @Column( name = "language_code" ) ) @MapKeyColumn(name = "language_code" )
@Fetch( FetchMode.JOIN ) @Fetch( FetchMode.JOIN )
@Filter( name = "selectedLocale", @Filter( name = "selectedLocale",
condition = " language_code = :param " ) condition = " language_code = :param " )

View File

@ -11,6 +11,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import org.hibernate.annotations.MapKey; import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.CollectionOfElements; import org.hibernate.annotations.CollectionOfElements;
@ -26,7 +27,7 @@ public class Atmosphere {
public Integer id; public Integer id;
@ManyToMany(cascade = CascadeType.ALL) @ManyToMany(cascade = CascadeType.ALL)
@MapKey(columns = {@Column(name="gas_name")}) @MapKeyColumn(name="gas_name")
public Map<String, Gas> gases = new HashMap<String, Gas>(); public Map<String, Gas> gases = new HashMap<String, Gas>();
@ManyToMany(cascade = CascadeType.ALL) @ManyToMany(cascade = CascadeType.ALL)

View File

@ -8,6 +8,7 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.MapKeyClass;
import org.hibernate.annotations.MapKey; import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.MapKeyManyToMany; import org.hibernate.annotations.MapKeyManyToMany;
@ -22,7 +23,7 @@ public class Brand {
private Long id; private Long id;
@ManyToMany(targetEntity = LuggageImpl.class) @ManyToMany(targetEntity = LuggageImpl.class)
@MapKey(targetElement = SizeImpl.class) @MapKeyClass(SizeImpl.class)
private Map<Size, Luggage> luggagesBySize = new HashMap<Size, Luggage>(); private Map<Size, Luggage> luggagesBySize = new HashMap<Size, Luggage>();
@ElementCollection(targetClass = SizeImpl.class) @ElementCollection(targetClass = SizeImpl.class)

View File

@ -1,11 +1,7 @@
//$Id$ //$Id$
package org.hibernate.test.annotations.target; package org.hibernate.test.annotations.target;
import java.util.Map;
import java.util.HashMap;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import org.hibernate.annotations.MapKey;
import javax.persistence.ManyToMany;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard