From 50ec688066a43d1bc4446d934c6987042a21a77e Mon Sep 17 00:00:00 2001 From: Adam Warski Date: Wed, 31 Dec 2008 11:29:37 +0000 Subject: [PATCH] HHH-3563, HHH-3561: component handling rework git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15744 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../RevisionInfoConfiguration.java | 10 +- .../metadata/AuditMetadataGenerator.java | 15 +- .../metadata/BasicMetadataGenerator.java | 173 ++++++------------ .../metadata/CollectionMetadataGenerator.java | 2 +- .../metadata/ComponentMetadataGenerator.java | 45 +++++ .../metadata/IdMetadataGenerator.java | 9 +- ...rsistentComponentPropertyAuditingData.java | 46 +++++ .../PersistentPropertyAuditingData.java | 2 +- .../envers/entities/PropertyData.java | 39 +++- ...pper.java => ComponentPropertyMapper.java} | 18 +- .../mapper/CompositeMapperBuilder.java | 2 +- .../entities/mapper/MultiPropertyMapper.java | 13 +- .../mapper/SubclassPropertyMapper.java | 16 +- .../entities/mapper/id/EmbeddedIdMapper.java | 3 +- .../entities/mapper/id/MultipleIdMapper.java | 3 +- .../entities/mapper/id/SingleIdMapper.java | 21 +-- .../tools/reflection/ReflectionTools.java | 6 +- 17 files changed, 237 insertions(+), 186 deletions(-) create mode 100644 envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java create mode 100644 envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentComponentPropertyAuditingData.java rename envers/src/main/java/org/hibernate/envers/entities/mapper/{MapPropertyMapper.java => ComponentPropertyMapper.java} (83%) diff --git a/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java b/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java index 42b32e8bca..d60afb47ca 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java @@ -59,8 +59,8 @@ public class RevisionInfoConfiguration { public RevisionInfoConfiguration() { revisionInfoEntityName = "org.hibernate.envers.DefaultRevisionEntity"; - revisionInfoIdData = new PropertyData("id", "field", null); - revisionInfoTimestampData = new PropertyData("timestamp", "field", null); + revisionInfoIdData = new PropertyData("id", "id", "field", null); + revisionInfoTimestampData = new PropertyData("timestamp", "timestamp", "field", null); revisionInfoTimestampType = "long"; revisionPropType = "integer"; @@ -109,11 +109,11 @@ public class RevisionInfoConfiguration { XClass revisionNumberClass = property.getType(); if (reflectionManager.equals(revisionNumberClass, Integer.class) || reflectionManager.equals(revisionNumberClass, Integer.TYPE)) { - revisionInfoIdData = new PropertyData(property.getName(), accessType, null); + revisionInfoIdData = new PropertyData(property.getName(), property.getName(), accessType, null); revisionNumberFound.set(); } else if (reflectionManager.equals(revisionNumberClass, Long.class) || reflectionManager.equals(revisionNumberClass, Long.TYPE)) { - revisionInfoIdData = new PropertyData(property.getName(), accessType, null); + revisionInfoIdData = new PropertyData(property.getName(), property.getName(), accessType, null); revisionNumberFound.set(); // The default is integer @@ -132,7 +132,7 @@ public class RevisionInfoConfiguration { XClass revisionTimestampClass = property.getType(); if (reflectionManager.equals(revisionTimestampClass, Long.class) || reflectionManager.equals(revisionTimestampClass, Long.TYPE)) { - revisionInfoTimestampData = new PropertyData(property.getName(), accessType, null); + revisionInfoTimestampData = new PropertyData(property.getName(), property.getName(), accessType, null); revisionTimestampFound.set(); } else { throw new MappingException("The field annotated with @RevisionTimestamp must be of type " + diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java index 1b80e25c4d..fb8f8161de 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java @@ -46,10 +46,7 @@ import org.hibernate.mapping.Join; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Value; -import org.hibernate.type.CollectionType; -import org.hibernate.type.ManyToOneType; -import org.hibernate.type.OneToOneType; -import org.hibernate.type.Type; +import org.hibernate.type.*; /** * @author Adam Warski (adam at warski dot org) @@ -62,6 +59,7 @@ public final class AuditMetadataGenerator { private final Element revisionInfoRelationMapping; private final BasicMetadataGenerator basicMetadataGenerator; + private final ComponentMetadataGenerator componentMetadataGenerator; private final IdMetadataGenerator idMetadataGenerator; private final ToOneRelationMetadataGenerator toOneRelationMetadataGenerator; @@ -79,6 +77,7 @@ public final class AuditMetadataGenerator { this.revisionInfoRelationMapping = revisionInfoRelationMapping; this.basicMetadataGenerator = new BasicMetadataGenerator(); + this.componentMetadataGenerator = new ComponentMetadataGenerator(this); this.idMetadataGenerator = new IdMetadataGenerator(this); this.toOneRelationMetadataGenerator = new ToOneRelationMetadataGenerator(this); @@ -109,13 +108,17 @@ public final class AuditMetadataGenerator { // only first pass if (firstPass) { if (basicMetadataGenerator.addBasic(parent, persistentPropertyAuditingData, value, currentMapper, - entityName, insertable, false)) { + insertable, false)) { // The property was mapped by the basic generator. return; } } - if (type instanceof ManyToOneType) { + if (type instanceof ComponentType) { + // both passes + componentMetadataGenerator.addComponent(parent, persistentPropertyAuditingData, value, currentMapper, + entityName, xmlMappingData, firstPass); + } else if (type instanceof ManyToOneType) { // only second pass if (!firstPass) { toOneRelationMetadataGenerator.addToOne(parent, persistentPropertyAuditingData, value, currentMapper, diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java index 8273b8d81f..5905324635 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java @@ -27,149 +27,82 @@ import java.util.Iterator; import java.util.Properties; import org.dom4j.Element; -import org.hibernate.envers.ModificationStore; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; import org.hibernate.envers.entities.mapper.SimpleMapperBuilder; import org.hibernate.mapping.Column; -import org.hibernate.mapping.Component; -import org.hibernate.mapping.Property; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Value; -import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeCustomType; import org.hibernate.type.CustomType; import org.hibernate.type.ImmutableType; import org.hibernate.type.MutableType; import org.hibernate.type.Type; -import org.hibernate.util.StringHelper; /** - * Generates metadata for basic properties: immutable types (including enums) and components + * Generates metadata for basic properties: immutable types (including enums). * @author Adam Warski (adam at warski dot org) */ public final class BasicMetadataGenerator { - boolean addBasic(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, Value value, - CompositeMapperBuilder mapper, String entityName, boolean insertable, boolean key) { - Type type = value.getType(); + boolean addBasic(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, + Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { + Type type = value.getType(); - if (type instanceof ComponentType) { - addComponent(parent, persistentPropertyAuditingData, value, mapper, entityName, key); - return true; - } else { - return addBasicNoComponent(parent, persistentPropertyAuditingData, value, mapper, insertable, key); - } - } + if (type instanceof ImmutableType || type instanceof MutableType) { + addSimpleValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); + } else if (type instanceof CustomType || type instanceof CompositeCustomType) { + addCustomValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); + } else if ("org.hibernate.type.PrimitiveByteArrayBlobType".equals(type.getClass().getName())) { + addSimpleValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); + } else { + return false; + } - boolean addBasicNoComponent(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, - Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { - Type type = value.getType(); + return true; + } - if (type instanceof ImmutableType || type instanceof MutableType) { - addSimpleValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); - } else if (type instanceof CustomType || type instanceof CompositeCustomType) { - addCustomValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); - } else if ("org.hibernate.type.PrimitiveByteArrayBlobType".equals(type.getClass().getName())) { - addSimpleValue(parent, persistentPropertyAuditingData, value, mapper, insertable, key); - } else { - return false; - } + @SuppressWarnings({"unchecked"}) + private void addSimpleValue(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, + Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { + if (parent != null) { + Element prop_mapping = MetadataTools.addProperty(parent, persistentPropertyAuditingData.getName(), + value.getType().getName(), insertable, key); + MetadataTools.addColumns(prop_mapping, (Iterator) value.getColumnIterator()); + } - return true; - } + // A null mapper means that we only want to add xml mappings + if (mapper != null) { + mapper.add(persistentPropertyAuditingData.getPropertyData()); + } + } - @SuppressWarnings({"unchecked"}) - private void addSimpleValue(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, - Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { - if (parent != null) { - Element prop_mapping = MetadataTools.addProperty(parent, persistentPropertyAuditingData.getName(), - value.getType().getName(), insertable, key); - MetadataTools.addColumns(prop_mapping, (Iterator) value.getColumnIterator()); - } + @SuppressWarnings({"unchecked"}) + private void addCustomValue(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, + Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { + if (parent != null) { + Element prop_mapping = MetadataTools.addProperty(parent, persistentPropertyAuditingData.getName(), + null, insertable, key); - // A null mapper means that we only want to add xml mappings - if (mapper != null) { - mapper.add(persistentPropertyAuditingData.getPropertyData()); - } - } + //CustomType propertyType = (CustomType) value.getType(); - @SuppressWarnings({"unchecked"}) - private void addCustomValue(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, - Value value, SimpleMapperBuilder mapper, boolean insertable, boolean key) { - if (parent != null) { - Element prop_mapping = MetadataTools.addProperty(parent, persistentPropertyAuditingData.getName(), - null, insertable, key); + Element type_mapping = prop_mapping.addElement("type"); + type_mapping.addAttribute("name", value.getType().getName()); - //CustomType propertyType = (CustomType) value.getType(); + if (value instanceof SimpleValue) { + Properties typeParameters = ((SimpleValue) value).getTypeParameters(); + if (typeParameters != null) { + for (java.util.Map.Entry paramKeyValue : typeParameters.entrySet()) { + Element type_param = type_mapping.addElement("param"); + type_param.addAttribute("name", (String) paramKeyValue.getKey()); + type_param.setText((String) paramKeyValue.getValue()); + } + } + } - Element type_mapping = prop_mapping.addElement("type"); - type_mapping.addAttribute("name", value.getType().getName()); + MetadataTools.addColumns(prop_mapping, (Iterator) value.getColumnIterator()); + } - if (value instanceof SimpleValue) { - Properties typeParameters = ((SimpleValue) value).getTypeParameters(); - if (typeParameters != null) { - for (java.util.Map.Entry paramKeyValue : typeParameters.entrySet()) { - Element type_param = type_mapping.addElement("param"); - type_param.addAttribute("name", (String) paramKeyValue.getKey()); - type_param.setText((String) paramKeyValue.getValue()); - } - } - } - - MetadataTools.addColumns(prop_mapping, (Iterator) value.getColumnIterator()); - } - - if (mapper != null) { - mapper.add(persistentPropertyAuditingData.getPropertyData()); - } - } - - private void addComponentClassName(Element any_mapping, Component comp) { - if (StringHelper.isNotEmpty(comp.getComponentClassName())) { - any_mapping.addAttribute("class", comp.getComponentClassName()); - } - } - - @SuppressWarnings({"unchecked"}) - private void addComponent(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, - Value value, CompositeMapperBuilder mapper, String entityName, boolean key) { - Element component_mapping = null; - Component prop_component = (Component) value; - - if (parent != null) { - /* - TODO: investigate relations inside components - if (!firstPass) { - // The required element already exists. - Iterator iter = parent.elementIterator("component"); - while (iter.hasNext()) { - Element child = iter.next(); - if (child.attribute("name").getText().equals(name)) { - component_mapping = child; - break; - } - } - - if (component_mapping == null) { - throw new AuditException("Element for component not found during second pass!"); - } - } else { - */ - - component_mapping = parent.addElement("component"); - component_mapping.addAttribute("name", persistentPropertyAuditingData.getName()); - - addComponentClassName(component_mapping, prop_component); - } - - CompositeMapperBuilder componentMapper = mapper.addComposite(persistentPropertyAuditingData.getPropertyData()); - - Iterator properties = (Iterator) prop_component.getPropertyIterator(); - while (properties.hasNext()) { - Property property = properties.next(); - addBasic(component_mapping, - new PersistentPropertyAuditingData(property.getName(), property.getPropertyAccessorName(), ModificationStore.FULL), - property.getValue(), componentMapper, entityName, property.isInsertable(), key); - } - } + if (mapper != null) { + mapper.add(persistentPropertyAuditingData.getPropertyData()); + } + } } diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java index 616b4c5576..8e0aa32da2 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java @@ -400,7 +400,7 @@ public final class CollectionMetadataGenerator { queryGeneratorBuilder.getCurrentIndex()); } else { // Last but one parameter: collection components are always insertable - boolean mapped = mainGenerator.getBasicMetadataGenerator().addBasicNoComponent(xmlMapping, + boolean mapped = mainGenerator.getBasicMetadataGenerator().addBasic(xmlMapping, new PersistentPropertyAuditingData(prefix, "field", ModificationStore.FULL), value, null, true, true); diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java new file mode 100644 index 0000000000..69e105853a --- /dev/null +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java @@ -0,0 +1,45 @@ +package org.hibernate.envers.configuration.metadata; + +import org.dom4j.Element; +import org.hibernate.mapping.Value; +import org.hibernate.mapping.Component; +import org.hibernate.mapping.Property; +import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.ModificationStore; + +import java.util.Iterator; + +/** + * Generates metadata for components. + * @author Adam Warski (adam at warski dot org) + */ +public final class ComponentMetadataGenerator { + private final AuditMetadataGenerator mainGenerator; + + ComponentMetadataGenerator(AuditMetadataGenerator auditMetadataGenerator) { + mainGenerator = auditMetadataGenerator; + } + + @SuppressWarnings({"unchecked"}) + public void addComponent(Element parent, PersistentPropertyAuditingData persistentPropertyAuditingData, + Value value, CompositeMapperBuilder mapper, String entityName, + EntityXmlMappingData xmlMappingData, boolean firstPass) { + Component prop_component = (Component) value; + + CompositeMapperBuilder componentMapper = mapper.addComponent(persistentPropertyAuditingData.getPropertyData()); + + // Adding all properties of the component + Iterator properties = (Iterator) prop_component.getPropertyIterator(); + while (properties.hasNext()) { + Property property = properties.next(); + // The name of the property in the entity will consist of the name of the component property concatenated + // with the name of the property in the bean, to avoid conflicts. + PersistentPropertyAuditingData propertyAuditingData = new PersistentComponentPropertyAuditingData( + persistentPropertyAuditingData.getName() + "_" + property.getName(), + property.getName(), property.getPropertyAccessorName(), ModificationStore.FULL); + + mainGenerator.addValue(parent, property.getValue(), componentMapper, + entityName, xmlMappingData, propertyAuditingData, property.isInsertable(), firstPass); + } + } +} diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java index 216207e64d..01b83615d2 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java @@ -62,7 +62,7 @@ public final class IdMetadataGenerator { if (!"_identifierMapper".equals(property.getName())) { if (propertyType instanceof ImmutableType) { // Last but one parameter: ids are always insertable - mainGenerator.getBasicMetadataGenerator().addBasicNoComponent(parent, + mainGenerator.getBasicMetadataGenerator().addBasic(parent, getIdPersistentPropertyAuditingData(property), property.getValue(), mapper, true, key); } else { @@ -107,12 +107,12 @@ public final class IdMetadataGenerator { mapper = new SingleIdMapper(); // Last but one parameter: ids are always insertable - mainGenerator.getBasicMetadataGenerator().addBasicNoComponent(rel_id_mapping, + mainGenerator.getBasicMetadataGenerator().addBasic(rel_id_mapping, getIdPersistentPropertyAuditingData(id_prop), id_prop.getValue(), mapper, true, false); // null mapper - the mapping where already added the first time, now we only want to generate the xml - mainGenerator.getBasicMetadataGenerator().addBasicNoComponent(orig_id_mapping, + mainGenerator.getBasicMetadataGenerator().addBasic(orig_id_mapping, getIdPersistentPropertyAuditingData(id_prop), id_prop.getValue(), null, true, true); } @@ -126,7 +126,8 @@ public final class IdMetadataGenerator { } private PropertyData getIdPropertyData(Property property) { - return new PropertyData(property.getName(), property.getPropertyAccessorName(), ModificationStore.FULL); + return new PropertyData(property.getName(), property.getName(), property.getPropertyAccessorName(), + ModificationStore.FULL); } private PersistentPropertyAuditingData getIdPersistentPropertyAuditingData(Property property) { diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentComponentPropertyAuditingData.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentComponentPropertyAuditingData.java new file mode 100644 index 0000000000..eb7c35e103 --- /dev/null +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentComponentPropertyAuditingData.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC. + * + * 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.envers.configuration.metadata; + +import org.hibernate.envers.ModificationStore; +import org.hibernate.envers.entities.PropertyData; + +/** + * @author Adam Warski (adam at warski dot org) + */ +public class PersistentComponentPropertyAuditingData extends PersistentPropertyAuditingData { + private final String beanName; + + public PersistentComponentPropertyAuditingData(String name, String beanName, String accessType, + ModificationStore store) { + super(name, accessType, store); + + this.beanName = beanName; + } + + public PropertyData getPropertyData() { + return new PropertyData(getName(), beanName, getAccessType(), getStore()); + } +} \ No newline at end of file diff --git a/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentPropertyAuditingData.java b/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentPropertyAuditingData.java index 1505a2d058..3d8e043f69 100644 --- a/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentPropertyAuditingData.java +++ b/envers/src/main/java/org/hibernate/envers/configuration/metadata/PersistentPropertyAuditingData.java @@ -88,6 +88,6 @@ public class PersistentPropertyAuditingData { } public PropertyData getPropertyData() { - return new PropertyData(name, accessType, store); + return new PropertyData(name, name, accessType, store); } } diff --git a/envers/src/main/java/org/hibernate/envers/entities/PropertyData.java b/envers/src/main/java/org/hibernate/envers/entities/PropertyData.java index ba1d8d176f..fc55130fb2 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/PropertyData.java +++ b/envers/src/main/java/org/hibernate/envers/entities/PropertyData.java @@ -31,6 +31,10 @@ import org.hibernate.envers.ModificationStore; */ public class PropertyData { private final String name; + /** + * Name of the property in the bean. + */ + private final String beanName; private final String accessType; private final ModificationStore store; @@ -41,17 +45,20 @@ public class PropertyData { */ public PropertyData(String newName, PropertyData propertyData) { this.name = newName; + this.beanName = propertyData.beanName; this.accessType = propertyData.accessType; this.store = propertyData.store; } /** * @param name Name of the property. + * @param beanName Name of the property in the bean. * @param accessType Accessor type for this property. * @param store How this property should be stored. */ - public PropertyData(String name, String accessType, ModificationStore store) { + public PropertyData(String name, String beanName, String accessType, ModificationStore store) { this.name = name; + this.beanName = beanName; this.accessType = accessType; this.store = store; } @@ -60,11 +67,39 @@ public class PropertyData { return name; } - public String getAccessType() { + public String getBeanName() { + return beanName; + } + + public String getAccessType() { return accessType; } public ModificationStore getStore() { return store; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PropertyData that = (PropertyData) o; + + if (accessType != null ? !accessType.equals(that.accessType) : that.accessType != null) return false; + if (beanName != null ? !beanName.equals(that.beanName) : that.beanName != null) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (store != that.store) return false; + + return true; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (beanName != null ? beanName.hashCode() : 0); + result = 31 * result + (accessType != null ? accessType.hashCode() : 0); + result = 31 * result + (store != null ? store.hashCode() : 0); + return result; + } } diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/MapPropertyMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java similarity index 83% rename from envers/src/main/java/org/hibernate/envers/entities/mapper/MapPropertyMapper.java rename to envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java index 6db45dfd3b..601fc50b34 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/MapPropertyMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java @@ -24,7 +24,6 @@ package org.hibernate.envers.entities.mapper; import java.io.Serializable; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,21 +41,21 @@ import org.hibernate.util.ReflectHelper; /** * @author Adam Warski (adam at warski dot org) */ -public class MapPropertyMapper implements PropertyMapper, CompositeMapperBuilder { +public class ComponentPropertyMapper implements PropertyMapper, CompositeMapperBuilder { private PropertyData propertyData; private ExtendedPropertyMapper delegate; - public MapPropertyMapper(PropertyData propertyData) { + public ComponentPropertyMapper(PropertyData propertyData) { this.propertyData = propertyData; this.delegate = new MultiPropertyMapper(); } - public void add(PropertyData propertyData) { + public void add(PropertyData propertyData) { delegate.add(propertyData); } - public CompositeMapperBuilder addComposite(PropertyData propertyData) { - return delegate.addComposite(propertyData); + public CompositeMapperBuilder addComponent(PropertyData propertyData) { + return delegate.addComponent(propertyData); } public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) { @@ -64,10 +63,7 @@ public class MapPropertyMapper implements PropertyMapper, CompositeMapperBuilder } public boolean mapToMapFromEntity(Map data, Object newObj, Object oldObj) { - Map newData = new HashMap(); - data.put(propertyData.getName(), newData); - - return delegate.mapToMapFromEntity(newData, newObj, oldObj); + return delegate.mapToMapFromEntity(data, newObj, oldObj); } public void mapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, Object primaryKey, AuditReaderImplementor versionsReader, Number revision) { @@ -81,7 +77,7 @@ public class MapPropertyMapper implements PropertyMapper, CompositeMapperBuilder try { Object subObj = ReflectHelper.getDefaultConstructor(getter.getReturnType()).newInstance(); setter.set(obj, subObj, null); - delegate.mapToEntityFromMap(verCfg, subObj, (Map) data.get(propertyData.getName()), primaryKey, versionsReader, revision); + delegate.mapToEntityFromMap(verCfg, subObj, data, primaryKey, versionsReader, revision); } catch (Exception e) { throw new AuditException(e); } diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java index 3d60450e7d..f913201535 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java @@ -29,6 +29,6 @@ import org.hibernate.envers.entities.PropertyData; * @author Adam Warski (adam at warski dot org) */ public interface CompositeMapperBuilder extends SimpleMapperBuilder { - public CompositeMapperBuilder addComposite(PropertyData propertyData); + public CompositeMapperBuilder addComponent(PropertyData propertyData); public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper); } diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java index b09f59af12..4b8328aac7 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java @@ -33,7 +33,6 @@ import org.hibernate.envers.reader.AuditReaderImplementor; import org.hibernate.envers.tools.reflection.ReflectionTools; import org.hibernate.envers.tools.Tools; -import org.hibernate.MappingException; import org.hibernate.collection.PersistentCollection; import org.hibernate.property.Getter; @@ -56,16 +55,16 @@ public class MultiPropertyMapper implements ExtendedPropertyMapper { propertyDatas.put(propertyData.getName(), propertyData); } - public CompositeMapperBuilder addComposite(PropertyData propertyData) { + public CompositeMapperBuilder addComponent(PropertyData propertyData) { if (properties.get(propertyData) != null) { - throw new MappingException("Mapping for " + propertyData.getName() + " already added!"); + // This is needed for second pass to work properly in the components mapper + return (CompositeMapperBuilder) properties.get(propertyData); } - MapPropertyMapper mapperBuilder = new MapPropertyMapper(propertyData); - properties.put(propertyData, mapperBuilder); - propertyDatas.put(propertyData.getName(), propertyData); + ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData); + addComposite(propertyData, componentMapperBuilder); - return mapperBuilder; + return componentMapperBuilder; } public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) { diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java index d6f5bdffe4..0fe4548102 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java @@ -70,18 +70,22 @@ public class SubclassPropertyMapper implements ExtendedPropertyMapper { PersistentCollection newColl, Serializable oldColl, Serializable id) { - List collectionChanges = parentMapper.mapCollectionChanges( + List parentCollectionChanges = parentMapper.mapCollectionChanges( referencingPropertyName, newColl, oldColl, id); - if (collectionChanges == null) { - return main.mapCollectionChanges(referencingPropertyName, newColl, oldColl, id); + List mainCollectionChanges = main.mapCollectionChanges( + referencingPropertyName, newColl, oldColl, id); + + if (parentCollectionChanges == null) { + return mainCollectionChanges; } else { - return collectionChanges; + parentCollectionChanges.addAll(mainCollectionChanges); + return parentCollectionChanges; } } - public CompositeMapperBuilder addComposite(PropertyData propertyData) { - return main.addComposite(propertyData); + public CompositeMapperBuilder addComponent(PropertyData propertyData) { + return main.addComponent(propertyData); } public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) { diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java index 713e06afab..54732c8a0a 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java @@ -88,8 +88,7 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl for (PropertyData propertyData : ids.keySet()) { String propertyName = propertyData.getName(); - ret.ids.put(propertyData, new SingleIdMapper(propertyName, - new PropertyData(prefix + propertyName, propertyData))); + ret.ids.put(propertyData, new SingleIdMapper(new PropertyData(prefix + propertyName, propertyData))); } return ret; diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java index d73a2ef4f6..3e1a4d9600 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java @@ -60,8 +60,7 @@ public class MultipleIdMapper extends AbstractCompositeIdMapper implements Simpl for (PropertyData propertyData : ids.keySet()) { String propertyName = propertyData.getName(); - ret.ids.put(propertyData, new SingleIdMapper(propertyName, - new PropertyData(prefix + propertyName, propertyData))); + ret.ids.put(propertyData, new SingleIdMapper(new PropertyData(prefix + propertyName, propertyData))); } return ret; diff --git a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java index 44e1e86e17..f54c09a7e1 100644 --- a/envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java +++ b/envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java @@ -38,19 +38,12 @@ import org.hibernate.property.Setter; * @author Adam Warski (adam at warski dot org) */ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBuilder { - private String beanPropertyName; private PropertyData propertyData; public SingleIdMapper() { } - public SingleIdMapper(String beanPropertyName, PropertyData propertyData) { - this.beanPropertyName = beanPropertyName; - this.propertyData = propertyData; - } - public SingleIdMapper(PropertyData propertyData) { - this.beanPropertyName = propertyData.getName(); this.propertyData = propertyData; } @@ -60,7 +53,6 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu } this.propertyData = propertyData; - this.beanPropertyName = propertyData.getName(); } public void mapToEntityFromMap(Object obj, Map data) { @@ -68,7 +60,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu return; } - Setter setter = ReflectionTools.getSetter(obj.getClass(), beanPropertyName, propertyData.getAccessType()); + Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyData); setter.set(obj, data.get(propertyData.getName()), null); } @@ -85,7 +77,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu return null; } - Getter getter = ReflectionTools.getGetter(data.getClass(), beanPropertyName, propertyData.getAccessType()); + Getter getter = ReflectionTools.getGetter(data.getClass(), propertyData); return getter.get(data); } @@ -99,7 +91,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu if (obj == null) { data.put(propertyData.getName(), null); } else { - Getter getter = ReflectionTools.getGetter(obj.getClass(), beanPropertyName, propertyData.getAccessType()); + Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyData); data.put(propertyData.getName(), getter.get(obj)); } } @@ -109,14 +101,13 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu return; } - Getter getter = ReflectionTools.getGetter(objFrom.getClass(), beanPropertyName, propertyData.getAccessType()); - Setter setter = ReflectionTools.getSetter(objTo.getClass(), beanPropertyName, propertyData.getAccessType()); + Getter getter = ReflectionTools.getGetter(objFrom.getClass(), propertyData); + Setter setter = ReflectionTools.getSetter(objTo.getClass(), propertyData); setter.set(objTo, getter.get(objFrom), null); } public IdMapper prefixMappedProperties(String prefix) { - return new SingleIdMapper(propertyData.getName(), - new PropertyData(prefix + propertyData.getName(), propertyData)); + return new SingleIdMapper(new PropertyData(prefix + propertyData.getName(), propertyData)); } public List mapToQueryParametersFromId(Object obj) { diff --git a/envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java b/envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java index 7db1f1ca65..ec9d7a4a95 100644 --- a/envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java +++ b/envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java @@ -59,7 +59,7 @@ public class ReflectionTools { } public static Getter getGetter(Class cls, PropertyData propertyData) { - return getGetter(cls, propertyData.getName(), propertyData.getAccessType()); + return getGetter(cls, propertyData.getBeanName(), propertyData.getAccessType()); } public static Getter getGetter(Class cls, String propertyName, String accessorType) { @@ -75,10 +75,10 @@ public class ReflectionTools { } public static Setter getSetter(Class cls, PropertyData propertyData) { - return getSetter(cls, propertyData.getName(), propertyData.getAccessType()); + return getSetter(cls, propertyData.getBeanName(), propertyData.getAccessType()); } - public static Setter getSetter(Class cls, String propertyName, String accessorType) { + private static Setter getSetter(Class cls, String propertyName, String accessorType) { Pair key = make(cls, propertyName); Setter value = setterCache.get(key); if (value == null) {