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.CollectionTable;
import javax.persistence.UniqueConstraint;
import javax.persistence.MapKeyColumn;
import org.hibernate.AnnotationException;
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.SimpleValueBinder;
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.Versioning;
import org.hibernate.id.MultipleHiLoPerTableGenerator;
@ -1538,14 +1541,20 @@ public final class AnnotationBinder {
);
}
org.hibernate.annotations.MapKey hibMapKeyAnn = property.getAnnotation(
org.hibernate.annotations.MapKey.class
);
Column[] keyColumns = null;
//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" );
Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
hibMapKeyAnn != null && hibMapKeyAnn.columns().length > 0 ?
hibMapKeyAnn.columns() :
null,
keyColumns,
null,
Nullability.FORCED_NOT_NULL,
propertyHolder,

View File

@ -39,6 +39,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.ElementCollection;
import javax.persistence.MapKeyColumn;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
@ -337,9 +338,11 @@ public abstract class CollectionBinder {
collection.setRole( StringHelper.qualify( propertyHolder.getPath(), 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(
"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(
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;
/*
* target has priority over reflection for the map key type
* JPA 2 has priority
*/
if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) {
target = property.getAnnotation( org.hibernate.annotations.MapKey.class ).targetElement();
}
else if ( property.isAnnotationPresent( MapKeyClass.class ) ) {
if ( property.isAnnotationPresent( MapKeyClass.class ) ) {
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 ) ) {
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",
joinColumns = @JoinColumn( name = "map_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() {
return properties;
}

View File

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

View File

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

View File

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

View File

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