Author: epbernard
Date: 2010-01-04 11:47:08 -0500 (Mon, 04 Jan 2010)
New Revision: 18393
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/Address.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/AttributeOverrideTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyInfo.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
Log:
HHH-4352 support for key. and value. for Map and @AttributeOverride. Managed to keep
support for legacy names as well.
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java 2010-01-04
16:03:21 UTC (rev 18392)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -98,8 +98,48 @@
/**
* Get column overriding, property first, then parent, then holder
+ * replace
+ * - "index" by "key" if present
+ * - "element" by "value" if present
+ * These rules are here to support both JPA 2 and legacy overriding rules.
+ *
+ * WARNING: this can conflict with user's expectations if:
+ * - the property uses some restricted values
+ * - the user has overridden the column
+ * But this is unlikely and avoid the need for a "legacy" flag
*/
public Column[] getOverriddenColumn(String propertyName) {
+ Column[] result = getExactOverriddenColumn( propertyName );
+ if (result == null) {
+ if ( propertyName.contains( ".key." ) ) {
+ //TODO cache the underlying regexp
+ result = getExactOverriddenColumn( propertyName.replace( ".key.",
".index." ) );
+ }
+ if ( result == null && propertyName.endsWith( ".key" ) ) {
+ //TODO cache the underlying regexp
+ result = getExactOverriddenColumn(
+ propertyName.substring( 0, propertyName.length() - ".key".length() ) +
".index"
+ );
+ }
+ if ( result == null && propertyName.contains( ".value." ) ) {
+ //TODO cache the underlying regexp
+ result = getExactOverriddenColumn( propertyName.replace( ".value.",
".element." ) );
+ }
+ if ( result == null && propertyName.endsWith( ".value" ) ) {
+ //TODO cache the underlying regexp
+ result = getExactOverriddenColumn(
+ propertyName.substring( 0, propertyName.length() - ".value".length() ) +
".element"
+ );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * find the overridden rules from the exact property name.
+ */
+ private Column[] getExactOverriddenColumn(String propertyName) {
Column[] override = null;
if ( parent != null ) {
override = parent.getOverriddenColumn( propertyName );
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-01-04
16:03:21 UTC (rev 18392)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -1672,6 +1672,7 @@
//nullify empty array
keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns :
null;
+ //"mapkey" is the legacy column name of the key column pre JPA 2
PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData,
"mapkey" );
Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
keyColumns,
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java 2010-01-04
16:03:21 UTC (rev 18392)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -1295,7 +1295,8 @@
throw new AssertionFailure( "Unable to guess collection property accessor
name" );
}
- PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY,
"element", elementClass );
+ //"value" is the JPA 2 prefix for map values (used to be
"element")
+ PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY,
"value", elementClass );
//TODO be smart with isNullable
Component component = AnnotationBinder.fillComponent(
holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY : AccessType.FIELD,
true,
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java 2010-01-04
16:03:21 UTC (rev 18392)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -174,10 +174,6 @@
else {
XClass elementClass;
AnnotatedClassType classType;
- // Map<String, javax.persistence.Column[]> columnOverrides =
PropertyHolderBuilder.buildColumnOverride(
- // property, StringHelper.qualify( collValue.getRole(), "element" )
- // );
- //FIXME the "element" is lost
PropertyHolder holder = null;
if ( BinderHelper.PRIMITIVE_NAMES.contains( mapKeyType ) ) {
classType = AnnotatedClassType.NONE;
@@ -227,8 +223,8 @@
}
//boolean propertyAccess = embeddable == null || AccessType.PROPERTY.equals(
embeddable.access() );
- //FIXME "index" is it right?
- PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY,
"index", elementClass );
+ //"key" is the JPA 2 prefix for map keys
+ PropertyData inferredData = new PropertyPreloadedData( AccessType.PROPERTY,
"key", elementClass );
//TODO be smart with isNullable
Component component = AnnotationBinder.fillComponent(
holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY :
AccessType.FIELD, true,
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/Address.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/Address.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/Address.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -0,0 +1,14 @@
+package org.hibernate.test.annotations.override;
+
+import javax.persistence.Embedded;
+import javax.persistence.Embeddable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Embeddable
+public class Address {
+ public String street;
+ public String city;
+ public String state;
+}
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/AttributeOverrideTest.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/AttributeOverrideTest.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/AttributeOverrideTest.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -0,0 +1,46 @@
+package org.hibernate.test.annotations.override;
+
+import java.util.Iterator;
+
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.Column;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class AttributeOverrideTest extends TestCase {
+ public void testMapKeyValue() throws Exception {
+ assertTrue( isColumnPresent( "PropertyRecord_parcels",
"ASSESSMENT") );
+ assertTrue( isColumnPresent( "PropertyRecord_parcels",
"SQUARE_FEET") );
+ assertTrue( isColumnPresent( "PropertyRecord_parcels",
"STREET_NAME") );
+ }
+
+ public boolean isColumnPresent(String tableName, String columnName) {
+ final Iterator<Table> tables = ( Iterator<Table> )
getCfg().getTableMappings();
+ while (tables.hasNext()) {
+ Table table = tables.next();
+ if (tableName.equals( table.getName() ) ) {
+ Iterator<Column> columns = (Iterator<Column>) table.getColumnIterator();
+ while ( columns.hasNext() ) {
+ Column column = columns.next();
+ if ( columnName.equals( column.getName() ) ) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ protected Class<?>[] getMappings() {
+ return new Class<?>[] {
+ PropertyInfo.class,
+ PropertyRecord.class,
+ Address.class
+ };
+ }
+}
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyInfo.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyInfo.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyInfo.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -0,0 +1,14 @@
+package org.hibernate.test.annotations.override;
+
+import java.math.BigDecimal;
+import javax.persistence.Embeddable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Embeddable
+public class PropertyInfo {
+ public Integer parcelNumber;
+ public Integer size;
+ public BigDecimal tax;
+}
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java 2010-01-04
16:47:08 UTC (rev 18393)
@@ -0,0 +1,28 @@
+package org.hibernate.test.annotations.override;
+
+import java.util.Map;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class PropertyRecord {
+ @Id
+ @GeneratedValue
+ public Long id;
+
+ @AttributeOverrides({
+ @AttributeOverride(name = "key.street", column = @Column(name =
"STREET_NAME")),
+ @AttributeOverride(name = "value.size", column = @Column(name =
"SQUARE_FEET")),
+ @AttributeOverride(name = "value.tax", column = @Column(name =
"ASSESSMENT"))
+ })
+ @ElementCollection
+ public Map<Address, PropertyInfo> parcels;
+}
\ No newline at end of file