HHH-4687 implement @MapKeyTemporal

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18433 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-01-07 17:33:23 +00:00
parent 461e2c10ac
commit a96f7bf729
6 changed files with 65 additions and 14 deletions

View File

@ -271,9 +271,13 @@ public class MapBinder extends CollectionBinder {
//do not call setType as it extract the type from @Type //do not call setType as it extract the type from @Type
//the algorithm generally does not apply for map key anyway //the algorithm generally does not apply for map key anyway
MapKey mapKeyAnn = property.getAnnotation( org.hibernate.annotations.MapKey.class ); MapKey mapKeyAnn = property.getAnnotation( org.hibernate.annotations.MapKey.class );
elementBinder.setKey(true);
if (mapKeyAnn != null && ! BinderHelper.isDefault( mapKeyAnn.type().type() ) ) { if (mapKeyAnn != null && ! BinderHelper.isDefault( mapKeyAnn.type().type() ) ) {
elementBinder.setExplicitType( mapKeyAnn.type() ); elementBinder.setExplicitType( mapKeyAnn.type() );
} }
else {
elementBinder.setType( property, elementClass );
}
mapValue.setIndex( elementBinder.make() ); mapValue.setIndex( elementBinder.make() );
} }
} }

View File

@ -30,7 +30,9 @@ import java.util.Date;
import java.util.Properties; import java.util.Properties;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.persistence.Lob; import javax.persistence.Lob;
import javax.persistence.MapKeyTemporal;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -70,6 +72,8 @@ public class SimpleValueBinder {
private Table table; private Table table;
private SimpleValue simpleValue; private SimpleValue simpleValue;
private boolean isVersion; private boolean isVersion;
//is a Map key
private boolean key;
public boolean isVersion() { public boolean isVersion() {
return isVersion; return isVersion;
@ -112,8 +116,9 @@ public class SimpleValueBinder {
Properties typeParameters = this.typeParameters; Properties typeParameters = this.typeParameters;
typeParameters.clear(); typeParameters.clear();
String type = BinderHelper.ANNOTATION_STRING_DEFAULT; String type = BinderHelper.ANNOTATION_STRING_DEFAULT;
if ( property.isAnnotationPresent( Temporal.class ) ) { if ( (!key && property.isAnnotationPresent( Temporal.class ) )
Temporal ann = property.getAnnotation( Temporal.class ); || (key && property.isAnnotationPresent( MapKeyTemporal.class ) )) {
boolean isDate; boolean isDate;
if ( mappings.getReflectionManager().equals( returnedClassOrElement, Date.class ) ) { if ( mappings.getReflectionManager().equals( returnedClassOrElement, Date.class ) ) {
isDate = true; isDate = true;
@ -127,8 +132,8 @@ public class SimpleValueBinder {
+ StringHelper.qualify( persistentClassName, propertyName ) + StringHelper.qualify( persistentClassName, propertyName )
); );
} }
final TemporalType temporalType = getTemporalType( property );
switch ( ann.value() ) { switch ( temporalType ) {
case DATE: case DATE:
type = isDate ? "date" : "calendar_date"; type = isDate ? "date" : "calendar_date";
break; break;
@ -145,7 +150,7 @@ public class SimpleValueBinder {
type = isDate ? "timestamp" : "calendar"; type = isDate ? "timestamp" : "calendar";
break; break;
default: default:
throw new AssertionFailure( "Unknown temporal type: " + ann.value() ); throw new AssertionFailure( "Unknown temporal type: " + temporalType );
} }
} }
else if ( property.isAnnotationPresent( Lob.class ) ) { else if ( property.isAnnotationPresent( Lob.class ) ) {
@ -219,10 +224,21 @@ public class SimpleValueBinder {
} }
explicitType = type; explicitType = type;
this.typeParameters = typeParameters; this.typeParameters = typeParameters;
Type annType = (Type) property.getAnnotation( Type.class ); Type annType = property.getAnnotation( Type.class );
setExplicitType( annType ); setExplicitType( annType );
} }
private TemporalType getTemporalType(XProperty property) {
if (key) {
MapKeyTemporal ann = property.getAnnotation( MapKeyTemporal.class );
return ann.value();
}
else {
Temporal ann = property.getAnnotation( Temporal.class );
return ann.value();
}
}
public void setExplicitType(String explicitType) { public void setExplicitType(String explicitType) {
this.explicitType = explicitType; this.explicitType = explicitType;
} }
@ -297,4 +313,8 @@ public class SimpleValueBinder {
} }
} }
public void setKey(boolean key) {
this.key = key;
}
} }

View File

@ -14,7 +14,6 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.test.annotations.Country; import org.hibernate.test.annotations.Country;
import org.hibernate.test.annotations.TestCase; import org.hibernate.test.annotations.TestCase;
import org.hibernate.util.StringHelper;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -204,14 +203,14 @@ public class CollectionElementTest extends TestCase {
public void testMapKeyType() throws Exception { public void testMapKeyType() throws Exception {
Matrix m = new Matrix(); Matrix m = new Matrix();
m.getValues().put( 1, 1.1f ); m.getMvalues().put( 1, 1.1f );
Session s = openSession(); Session s = openSession();
Transaction tx = s.beginTransaction(); Transaction tx = s.beginTransaction();
s.persist( m ); s.persist( m );
s.flush(); s.flush();
s.clear(); s.clear();
m = (Matrix) s.get( Matrix.class, m.getId() ); m = (Matrix) s.get( Matrix.class, m.getId() );
assertEquals( 1.1f, m.getValues().get( 1 ) ); assertEquals( 1.1f, m.getMvalues().get( 1 ) );
tx.rollback(); tx.rollback();
s.close(); s.close();
} }

View File

@ -27,7 +27,7 @@ public class Matrix {
@ElementCollection @ElementCollection
@Sort(type = SortType.NATURAL) @Sort(type = SortType.NATURAL)
@Type(type = "float") @Type(type = "float")
private SortedMap<Integer, Float> values = new TreeMap<Integer, Float>(); private SortedMap<Integer, Float> mvalues = new TreeMap<Integer, Float>();
public Integer getId() { public Integer getId() {
return id; return id;
@ -37,11 +37,11 @@ public class Matrix {
this.id = id; this.id = id;
} }
public Map<Integer, Float> getValues() { public Map<Integer, Float> getMvalues() {
return values; return mvalues;
} }
public void setValues(SortedMap<Integer, Float> values) { public void setMvalues(SortedMap<Integer, Float> mValues) {
this.values = values; this.mvalues = mValues;
} }
} }

View File

@ -1,9 +1,11 @@
//$Id$ //$Id$
package org.hibernate.test.annotations.indexcoll; package org.hibernate.test.annotations.indexcoll;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
@ -13,6 +15,8 @@ import javax.persistence.JoinTable;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn; import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyJoinColumn; import javax.persistence.MapKeyJoinColumn;
import javax.persistence.MapKeyTemporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.MapKey; import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.CollectionOfElements; import org.hibernate.annotations.CollectionOfElements;
@ -30,6 +34,10 @@ public class Atmosphere {
@MapKeyColumn(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>();
@MapKeyTemporal(TemporalType.DATE)
@ElementCollection
public Map<Date, String> colorPerDate = new HashMap<Date,String>();
@ManyToMany(cascade = CascadeType.ALL) @ManyToMany(cascade = CascadeType.ALL)
@MapKeyJoinColumn(name="gas_id" ) @MapKeyJoinColumn(name="gas_id" )
@JoinTable(name = "Gas_per_key") @JoinTable(name = "Gas_per_key")

View File

@ -2,6 +2,7 @@
package org.hibernate.test.annotations.indexcoll; package org.hibernate.test.annotations.indexcoll;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -442,6 +443,25 @@ public class IndexedCollectionTest extends TestCase {
s.close(); s.close();
} }
public void testTemporalKeyMap() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Atmosphere atm = new Atmosphere();
atm.colorPerDate.put( new Date(1234567000), "red" );
s.persist( atm );
s.flush();
s.clear();
atm = (Atmosphere) s.get( Atmosphere.class, atm.id );
assertEquals( 1, atm.colorPerDate.size() );
final Date date = atm.colorPerDate.keySet().iterator().next();
final long diff = new Date( 1234567000 ).getTime() - date.getTime();
assertTrue( "24h diff max", diff > 0 && diff < 24*60*60*1000 );
tx.rollback();
s.close();
}
public void testMapKeyEntityEntity() throws Exception { public void testMapKeyEntityEntity() throws Exception {
Session s = openSession(); Session s = openSession();
Transaction tx = s.beginTransaction(); Transaction tx = s.beginTransaction();