@Deprecated public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) { final Type type = property.getValue().getType(); // we need to dirty check collections, since they can cause an owner // version number increment // we need to dirty check many-to-ones with not-found="ignore" in order // to update the cache (not the database), since in this case a null // entity reference can lose information boolean alwaysDirtyCheck = type.isAssociationType() && ((AssociationType) type).isAlwaysDirtyChecked(); return new StandardProperty( property.getName(), type, lazyAvailable && property.isLazy(), property.isInsertable(), property.isUpdateable(), property.getValueGenerationStrategy(), property.isOptional(), alwaysDirtyCheck || property.isUpdateable(), property.isOptimisticLocked(), property.getCascadeStyle(), property.getValue().getFetchMode()); }
protected void applyCacheSettings(Configuration configuration) { if (getCacheConcurrencyStrategy() != null) { Iterator itr = configuration.getClassMappings(); while (itr.hasNext()) { PersistentClass clazz = (PersistentClass) itr.next(); Iterator props = clazz.getPropertyClosureIterator(); boolean hasLob = false; while (props.hasNext()) { Property prop = (Property) props.next(); if (prop.getValue().isSimpleValue()) { String type = ((SimpleValue) prop.getValue()).getTypeName(); if ("blob".equals(type) || "clob".equals(type)) { hasLob = true; } if (Blob.class.getName().equals(type) || Clob.class.getName().equals(type)) { hasLob = true; } } } if (!hasLob && !clazz.isInherited() && overrideCacheStrategy()) { configuration.setCacheConcurrencyStrategy( clazz.getEntityName(), getCacheConcurrencyStrategy()); } } itr = configuration.getCollectionMappings(); while (itr.hasNext()) { Collection coll = (Collection) itr.next(); configuration.setCollectionCacheConcurrencyStrategy( coll.getRole(), getCacheConcurrencyStrategy()); } } }
/** * Generates a VersionProperty representation for an entity mapping given its version mapping * Property. * * @param property The version mapping Property. * @param lazyAvailable Is property lazy loading currently available. * @return The appropriate VersionProperty definition. */ public static VersionProperty buildVersionProperty( EntityPersister persister, SessionFactoryImplementor sessionFactory, int attributeNumber, Property property, boolean lazyAvailable) { String mappedUnsavedValue = ((KeyValue) property.getValue()).getNullValue(); VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( mappedUnsavedValue, getGetter(property), (VersionType) property.getType(), getConstructor(property.getPersistentClass())); boolean lazy = lazyAvailable && property.isLazy(); return new VersionProperty( persister, sessionFactory, attributeNumber, property.getName(), property.getValue().getType(), new BaselineAttributeInformation.Builder() .setLazy(lazy) .setInsertable(property.isInsertable()) .setUpdateable(property.isUpdateable()) .setValueGenerationStrategy(property.getValueGenerationStrategy()) .setNullable(property.isOptional()) .setDirtyCheckable(property.isUpdateable() && !lazy) .setVersionable(property.isOptimisticLocked()) .setCascadeStyle(property.getCascadeStyle()) .createInformation(), unsavedValue); }
protected boolean isRequiredInConstructor(Property field) { if (hasMetaAttribute(field, "default-value")) { return false; } if (field.getValue() != null) { if (!field.isOptional() && (field.getValueGenerationStrategy() == null || field .getValueGenerationStrategy() .getGenerationTiming() .equals(GenerationTiming.NEVER))) { return true; } else if (field.getValue() instanceof Component) { Component c = (Component) field.getValue(); Iterator<?> it = c.getPropertyIterator(); while (it.hasNext()) { Property prop = (Property) it.next(); if (isRequiredInConstructor(prop)) { return true; } } } } return false; }
private void buildSessionFactory(String[] files) throws Exception { if (getSessions() != null) getSessions().close(); try { setCfg(new Configuration()); cfg.addProperties(getExtraProperties()); if (recreateSchema()) { cfg.setProperty(Environment.HBM2DDL_AUTO, "create-drop"); } for (int i = 0; i < files.length; i++) { if (!files[i].startsWith("net/")) files[i] = getBaseForMappings() + files[i]; getCfg().addResource(files[i], TestCase.class.getClassLoader()); } setDialect(Dialect.getDialect()); configure(cfg); if (getCacheConcurrencyStrategy() != null) { Iterator iter = cfg.getClassMappings(); while (iter.hasNext()) { PersistentClass clazz = (PersistentClass) iter.next(); Iterator props = clazz.getPropertyClosureIterator(); boolean hasLob = false; while (props.hasNext()) { Property prop = (Property) props.next(); if (prop.getValue().isSimpleValue()) { String type = ((SimpleValue) prop.getValue()).getTypeName(); if ("blob".equals(type) || "clob".equals(type)) hasLob = true; if (Blob.class.getName().equals(type) || Clob.class.getName().equals(type)) hasLob = true; } } if (!hasLob && !clazz.isInherited() && overrideCacheStrategy()) { cfg.setCacheConcurrencyStrategy(clazz.getEntityName(), getCacheConcurrencyStrategy()); } } iter = cfg.getCollectionMappings(); while (iter.hasNext()) { Collection coll = (Collection) iter.next(); cfg.setCollectionCacheConcurrencyStrategy(coll.getRole(), getCacheConcurrencyStrategy()); } } setSessions(getCfg().buildSessionFactory(/*new TestInterceptor()*/ )); afterSessionFactoryBuilt(); } catch (Exception e) { e.printStackTrace(); throw e; } }
private void mapPropertyToIndex(Property prop, int i) { propertyIndexes.put(prop.getName(), i); if (prop.getValue() instanceof Component) { Iterator iter = ((Component) prop.getValue()).getPropertyIterator(); while (iter.hasNext()) { Property subprop = (Property) iter.next(); propertyIndexes.put(prop.getName() + '.' + subprop.getName(), i); } } }
private ValueInclusion determineUpdateValueGenerationType( Property mappingProperty, NonIdentifierAttribute runtimeProperty) { if (isUpdateGenerated(runtimeProperty)) { return ValueInclusion.FULL; } else if (mappingProperty.getValue() instanceof Component) { if (hasPartialUpdateComponentGeneration((Component) mappingProperty.getValue())) { return ValueInclusion.PARTIAL; } } return ValueInclusion.NONE; }
private ValueInclusion determineInsertValueGenerationType( Property mappingProperty, StandardProperty runtimeProperty) { if (runtimeProperty.isInsertGenerated()) { return ValueInclusion.FULL; } else if (mappingProperty.getValue() instanceof Component) { if (hasPartialInsertComponentGeneration((Component) mappingProperty.getValue())) { return ValueInclusion.PARTIAL; } } return ValueInclusion.NONE; }
private Property getConstrainedOneToOne(RootClass rc) { Iterator propertyClosureIterator = rc.getPropertyClosureIterator(); while (propertyClosureIterator.hasNext()) { Property property = (Property) propertyClosureIterator.next(); if (property.getValue() instanceof OneToOne) { OneToOne oto = (OneToOne) property.getValue(); if (oto.isConstrained()) { return property; } } } return null; }
private boolean hasPartialUpdateComponentGeneration(Component component) { Iterator subProperties = component.getPropertyIterator(); while (subProperties.hasNext()) { Property prop = (Property) subProperties.next(); if (isUpdateGenerated(prop)) { return true; } else if (prop.getValue() instanceof Component) { if (hasPartialUpdateComponentGeneration((Component) prop.getValue())) { return true; } } } return false; }
private boolean hasPartialInsertComponentGeneration(Component component) { Iterator subProperties = component.getPropertyIterator(); while (subProperties.hasNext()) { Property prop = (Property) subProperties.next(); if (prop.getGeneration() == PropertyGeneration.ALWAYS || prop.getGeneration() == PropertyGeneration.INSERT) { return true; } else if (prop.getValue() instanceof Component) { if (hasPartialInsertComponentGeneration((Component) prop.getValue())) { return true; } } } return false; }
@SuppressWarnings({"unchecked"}) private String searchMappedBy(PersistentClass referencedClass, Table collectionTable) { Iterator<Property> properties = referencedClass.getPropertyIterator(); while (properties.hasNext()) { Property property = properties.next(); if (property.getValue() instanceof Collection) { // The equality is intentional. We want to find a collection property with the same // collection table. //noinspection ObjectEquality if (((Collection) property.getValue()).getCollectionTable() == collectionTable) { return property.getName(); } } } return null; }
public boolean isComponent(Property property) { Value value = property.getValue(); if (value != null && value instanceof Component) { return true; } else { return false; } }
public String generateBasicAnnotation(Property property) { StringBuffer annotations = new StringBuffer(" "); if (property.getValue() instanceof SimpleValue) { if (hasVersionProperty()) if (property.equals(getVersionProperty())) buildVersionAnnotation(annotations); String typeName = ((SimpleValue) property.getValue()).getTypeName(); if ("date".equals(typeName) || "java.sql.Date".equals(typeName)) { buildTemporalAnnotation(annotations, "DATE"); } else if ("timestamp".equals(typeName) || "java.sql.Timestamp".equals(typeName)) { buildTemporalAnnotation(annotations, "TIMESTAMP"); } else if ("time".equals(typeName) || "java.sql.Time".equals(typeName)) { buildTemporalAnnotation(annotations, "TIME"); } // TODO: calendar etc. ? } return annotations.toString(); }
@SuppressWarnings("unchecked") private void createPropertiesGroupMapping(Property property) { final Component component = (Component) property.getValue(); final Iterator<Property> componentProperties = component.getPropertyIterator(); while (componentProperties.hasNext()) { final Property componentProperty = componentProperties.next(); propertiesGroupMapping.put(componentProperty.getName(), component.getNodeName()); } }
private static void collectComponents( Map<String, Component> components, Iterator<Property> iter) { while (iter.hasNext()) { Property property = iter.next(); if (!"embedded".equals(property.getPropertyAccessorName()) && // HBX-267, embedded property for <properties> should not be generated as component. property.getValue() instanceof Component) { Component comp = (Component) property.getValue(); addComponent(components, comp); } else if (property.getValue() instanceof Collection) { // compisite-element in collection Collection collection = (Collection) property.getValue(); if (collection.getElement() instanceof Component) { Component comp = (Component) collection.getElement(); addComponent(components, comp); } } } }
private Property bindMeta(Property property, TableIdentifier identifier) { Iterator columnIterator = property.getValue().getColumnIterator(); while (columnIterator.hasNext()) { Column col = (Column) columnIterator.next(); Map map = revengStrategy.columnToMetaAttributes(identifier, col.getName()); if (map != null) { // TODO: merge from each column ? property.setMetaAttributes(map); } } return property; }
@SuppressWarnings({"unchecked"}) private String searchMappedBy(PersistentClass referencedClass, Collection collectionValue) { Iterator<Property> assocClassProps = referencedClass.getPropertyIterator(); while (assocClassProps.hasNext()) { Property property = assocClassProps.next(); if (Tools.iteratorsContentEqual( property.getValue().getColumnIterator(), collectionValue.getKey().getColumnIterator())) { return property.getName(); } } return null; }
private static GenerationStrategyPair buildGenerationStrategyPair( final SessionFactoryImplementor sessionFactory, final Property mappingProperty) { final ValueGeneration valueGeneration = mappingProperty.getValueGenerationStrategy(); if (valueGeneration != null && valueGeneration.getGenerationTiming() != GenerationTiming.NEVER) { // the property is generated in full. build the generation strategy pair. if (valueGeneration.getValueGenerator() != null) { // in-memory generation return new GenerationStrategyPair( FullInMemoryValueGenerationStrategy.create(valueGeneration)); } else { // in-db generation return new GenerationStrategyPair(create(sessionFactory, mappingProperty, valueGeneration)); } } else if (mappingProperty.getValue() instanceof Component) { final CompositeGenerationStrategyPairBuilder builder = new CompositeGenerationStrategyPairBuilder(mappingProperty); interpretPartialCompositeValueGeneration( sessionFactory, (Component) mappingProperty.getValue(), builder); return builder.buildPair(); } return NO_GEN_PAIR; }
private void handleProperty(EntityType entityType, Class<?> cl, org.hibernate.mapping.Property p) throws NoSuchMethodException, ClassNotFoundException { Type propertyType = getType(cl, p.getName()); if (p.isComposite()) { Class<?> embeddedClass = Class.forName(propertyType.getFullName()); EntityType embeddedType = createEmbeddableType(embeddedClass); Iterator<?> properties = ((Component) p.getValue()).getPropertyIterator(); while (properties.hasNext()) { handleProperty( embeddedType, embeddedClass, (org.hibernate.mapping.Property) properties.next()); } propertyType = embeddedType; } else if (propertyType.getCategory() == TypeCategory.ENTITY) { propertyType = createEntityType(Class.forName(propertyType.getFullName())); } AnnotatedElement annotated = getAnnotatedElement(cl, p.getName()); Property property = createProperty(entityType, p.getName(), propertyType, annotated); entityType.addProperty(property); }
@SuppressWarnings("unchecked") private void addSubElement(Property property, ValidatableElement element) { if (property != null && property.isComposite() && !property.isBackRef()) { Component component = (Component) property.getValue(); if (component.isEmbedded()) return; PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(property, EntityMode.POJO); Getter getter = accessor.getGetter(element.clazz, property.getName()); ClassValidator validator = new ClassValidator(getter.getReturnType()); ValidatableElement subElement = new ValidatableElement(getter.getReturnType(), validator, getter); Iterator properties = component.getPropertyIterator(); while (properties.hasNext()) { addSubElement((Property) properties.next(), subElement); } if (subElement.getSubElements().size() != 0 || subElement.validator.hasValidationRules()) { element.addSubElement(subElement); } } }
public String generateAnnColumnAnnotation(Property property) { StringBuffer annotations = new StringBuffer(" "); boolean insertable = property.isInsertable(); boolean updatable = property.isUpdateable(); if (property.isComposite()) { annotations.append("@" + importType("javax.persistence.AttributeOverrides") + "( {"); Component component = (Component) property.getValue(); Iterator<?> subElements = component.getPropertyIterator(); buildRecursiveAttributeOverride(subElements, null, property, annotations); annotations.setLength(annotations.length() - 2); annotations.append(" } )"); } else { if (property.getColumnSpan() == 1) { Selectable selectable = (Selectable) property.getColumnIterator().next(); buildColumnAnnotation(selectable, annotations, insertable, updatable); } else { Iterator<?> columns = property.getColumnIterator(); annotations .append("@") .append(importType("org.hibernate.annotations.Columns")) .append("( { "); while (columns.hasNext()) { Selectable selectable = (Selectable) columns.next(); if (selectable.isFormula()) { // TODO formula in multicolumns not supported by annotations // annotations.append("/* TODO formula in multicolumns not supported by annotations // */"); } else { annotations.append("\n "); buildColumnAnnotation(selectable, annotations, insertable, updatable); annotations.append(", "); } } annotations.setLength(annotations.length() - 2); annotations.append(" } )"); } } return annotations.toString(); }
@SuppressWarnings({"unchecked"}) private boolean addIdProperties( Element parent, Iterator<Property> properties, SimpleMapperBuilder mapper, boolean key, boolean audited) { while (properties.hasNext()) { Property property = properties.next(); Type propertyType = property.getType(); if (!"_identifierMapper".equals(property.getName())) { // Last but one parameter: ids are always insertable boolean added = mainGenerator .getBasicMetadataGenerator() .addBasic( parent, getIdPersistentPropertyAuditingData(property), property.getValue(), mapper, true, key); if (!added) { // If the entity is audited, and a non-supported id component is used, throwing an // exception. // If the entity is not audited, then we simply don't support this entity, even in // target relation mode not audited. if (audited) { throw new MappingException("Type not supported: " + propertyType.getClass().getName()); } else { return false; } } } } return true; }
/** * calculated the max length of an attribute of type String * * @param c Cluster that holds the attribute * @param attributeName name of the attribute * @return max allowed length of the attribute */ public int getLenthOfStringAttribute(ICluster c, String attributeName) { Assert.notNull(c, "c may not be null"); Assert.notNull(attributeName, "attributeName may not be null"); PersistentClass pc = cfg.getClassMapping(c.getDaoClass().getName()); if (pc == null) throw new ConfigurationException( "Persistent Dao Class from Cluster " + c.getClass().getName() + " is not Hibernate configured"); Property p = pc.getProperty(attributeName); if (p == null) throw new ConfigurationException( "Property " + attributeName + " in cluster " + c.getClass().getName() + " not found"); Iterator<Column> i = (Iterator<Column>) p.getValue().getColumnIterator(); Column column = i.next(); return column.getLength(); }
/** * Builds the <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association * using a join tables. * * <p>Note:<br> * * <ul> * <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the * other side. * <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</i>. */ private Join buildJoinFromMappedBySide( PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) { Join join = new Join(); join.setPersistentClass(persistentClass); // no check constraints available on joins join.setTable(originalJoin.getTable()); join.setInverse(true); SimpleValue key = new DependantValue(mappings, join.getTable(), persistentClass.getIdentifier()); // TODO support @ForeignKey join.setKey(key); join.setSequentialSelect(false); // TODO support for inverse and optional join.setOptional(true); // perhaps not quite per-spec, but a Good Thing anyway key.setCascadeDeleteEnabled(false); Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator(); while (mappedByColumns.hasNext()) { Column column = (Column) mappedByColumns.next(); Column copy = new Column(); copy.setLength(column.getLength()); copy.setScale(column.getScale()); copy.setValue(key); copy.setName(column.getQuotedName()); copy.setNullable(column.isNullable()); copy.setPrecision(column.getPrecision()); copy.setUnique(column.isUnique()); copy.setSqlType(column.getSqlType()); copy.setCheckConstraint(column.getCheckConstraint()); copy.setComment(column.getComment()); copy.setDefaultValue(column.getDefaultValue()); key.addColumn(copy); } persistentClass.addJoin(join); return join; }
private void buildRecursiveAttributeOverride( Iterator<?> subElements, String path, Property property, StringBuffer annotations) { while (subElements.hasNext()) { Property subProperty = (Property) subElements.next(); if (subProperty.isComposite()) { if (path != null) { path = path + "."; } else { path = ""; } path = path + subProperty.getName(); Component component = (Component) subProperty.getValue(); buildRecursiveAttributeOverride( component.getPropertyIterator(), path, subProperty, annotations); } else { Iterator<?> columns = subProperty.getColumnIterator(); Selectable selectable = (Selectable) columns.next(); if (selectable.isFormula()) { // TODO formula in multicolumns not supported by annotations } else { annotations .append("\n ") .append("@") .append(importType("javax.persistence.AttributeOverride")) .append("(name=\""); if (path != null) { annotations.append(path).append("."); } annotations.append(subProperty.getName()).append("\"").append(", column="); buildColumnAnnotation( selectable, annotations, subProperty.isInsertable(), subProperty.isUpdateable()); annotations.append(" ), "); } } } }
@SuppressWarnings({"unchecked"}) public void wrapUp() { LOG.trace("Wrapping up metadata context..."); // we need to process types from superclasses to subclasses for (Object mapping : orderedMappings) { if (PersistentClass.class.isAssignableFrom(mapping.getClass())) { @SuppressWarnings("unchecked") final PersistentClass safeMapping = (PersistentClass) mapping; LOG.trace("Starting entity [" + safeMapping.getEntityName() + "]"); try { final EntityTypeImpl<?> jpa2Mapping = entityTypesByPersistentClass.get(safeMapping); applyIdMetadata(safeMapping, jpa2Mapping); applyVersionAttribute(safeMapping, jpa2Mapping); Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator(); while (properties.hasNext()) { final Property property = properties.next(); if (property.getValue() == safeMapping.getIdentifierMapper()) { // property represents special handling for id-class mappings but we have already // accounted for the embedded property mappings in #applyIdMetadata && // #buildIdClassAttributes continue; } if (safeMapping.isVersioned() && property == safeMapping.getVersion()) { // skip the version property, it was already handled previously. continue; } final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property); if (attribute != null) { jpa2Mapping.getBuilder().addAttribute(attribute); } } jpa2Mapping.lock(); populateStaticMetamodel(jpa2Mapping); } finally { LOG.trace("Completed entity [" + safeMapping.getEntityName() + "]"); } } else if (MappedSuperclass.class.isAssignableFrom(mapping.getClass())) { @SuppressWarnings("unchecked") final MappedSuperclass safeMapping = (MappedSuperclass) mapping; LOG.trace("Starting mapped superclass [" + safeMapping.getMappedClass().getName() + "]"); try { final MappedSuperclassTypeImpl<?> jpa2Mapping = mappedSuperclassByMappedSuperclassMapping.get(safeMapping); applyIdMetadata(safeMapping, jpa2Mapping); applyVersionAttribute(safeMapping, jpa2Mapping); Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator(); while (properties.hasNext()) { final Property property = properties.next(); if (safeMapping.isVersioned() && property == safeMapping.getVersion()) { // skip the version property, it was already handled previously. continue; } final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property); if (attribute != null) { jpa2Mapping.getBuilder().addAttribute(attribute); } } jpa2Mapping.lock(); populateStaticMetamodel(jpa2Mapping); } finally { LOG.trace("Completed mapped superclass [" + safeMapping.getMappedClass().getName() + "]"); } } else { throw new AssertionFailure("Unexpected mapping type: " + mapping.getClass()); } } for (EmbeddableTypeImpl embeddable : embeddables.values()) { populateStaticMetamodel(embeddable); } }
public String getFieldInitialization(Property p, boolean useGenerics) { if (hasMetaAttribute(p, "default-value")) { return MetaAttributeHelper.getMetaAsString(p.getMetaAttribute("default-value")); } if (c2j.getJavaTypeName(p, false) == null) { throw new IllegalArgumentException(); } else if (p.getValue() instanceof Collection) { Collection col = (Collection) p.getValue(); DefaultInitializor initialization = (DefaultInitializor) col.accept( new DefaultValueVisitor(true) { public Object accept(Bag o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(org.hibernate.mapping.List o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(org.hibernate.mapping.Map o) { if (o.isSorted()) { return new DefaultInitializor("java.util.TreeMap", false); } else { return new DefaultInitializor("java.util.HashMap", true); } } public Object accept(IdentifierBag o) { return new DefaultInitializor("java.util.ArrayList", true); } public Object accept(Set o) { if (o.isSorted()) { return new DefaultInitializor("java.util.TreeSet", false); } else { return new DefaultInitializor("java.util.HashSet", true); } } public Object accept(PrimitiveArray o) { return null; // TODO: default init for arrays ? } public Object accept(Array o) { return null; // TODO: default init for arrays ? } }); if (initialization != null) { String comparator = null; String decl = null; if (col.isSorted()) { comparator = col.getComparatorClassName(); } if (useGenerics) { decl = c2j.getGenericCollectionDeclaration((Collection) p.getValue(), true, importContext); } return initialization.getDefaultValue(comparator, decl, this); } else { return null; } } else { return null; } }
public GenerationStrategyPair buildPair() { if (hadInMemoryGeneration && hadInDatabaseGeneration) { throw new ValueGenerationStrategyException( "Composite attribute [" + mappingProperty.getName() + "] contained both in-memory" + " and in-database value generation"); } else if (hadInMemoryGeneration) { throw new NotYetImplementedException( "Still need to wire in composite in-memory value generation"); } else if (hadInDatabaseGeneration) { final Component composite = (Component) mappingProperty.getValue(); // we need the numbers to match up so we can properly handle 'referenced sql column values' if (inDatabaseStrategies.size() != composite.getPropertySpan()) { throw new ValueGenerationStrategyException( "Internal error : mismatch between number of collected in-db generation strategies" + " and number of attributes for composite attribute : " + mappingProperty.getName()); } // the base-line values for the aggregated InDatabaseValueGenerationStrategy we will build // here. GenerationTiming timing = GenerationTiming.INSERT; boolean referenceColumns = false; String[] columnValues = new String[composite.getColumnSpan()]; // start building the aggregate values int propertyIndex = -1; int columnIndex = 0; Iterator subProperties = composite.getPropertyIterator(); while (subProperties.hasNext()) { propertyIndex++; final Property subProperty = (Property) subProperties.next(); final InDatabaseValueGenerationStrategy subStrategy = inDatabaseStrategies.get(propertyIndex); if (subStrategy.getGenerationTiming() == GenerationTiming.ALWAYS) { // override the base-line to the more often "ALWAYS"... timing = GenerationTiming.ALWAYS; } if (subStrategy.referenceColumnsInSql()) { // override base-line value referenceColumns = true; } if (subStrategy.getReferencedColumnValues() != null) { if (subStrategy.getReferencedColumnValues().length != subProperty.getColumnSpan()) { throw new ValueGenerationStrategyException( "Internal error : mismatch between number of collected 'referenced column values'" + " and number of columns for composite attribute : " + mappingProperty.getName() + '.' + subProperty.getName()); } System.arraycopy( subStrategy.getReferencedColumnValues(), 0, columnValues, columnIndex, subProperty.getColumnSpan()); } } // then use the aggregated values to build the InDatabaseValueGenerationStrategy return new GenerationStrategyPair( new InDatabaseValueGenerationStrategyImpl(timing, referenceColumns, columnValues)); } else { return NO_GEN_PAIR; } }
@SuppressWarnings({"unchecked"}) public void doSecondPass(Map persistentClasses) throws MappingException { PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get(referencedEntityName); // TODO better error names if (referencedPersistentClass == null) { throw new AnnotationException("Unknown entity name: " + referencedEntityName); } if (!(referencedPersistentClass.getIdentifier() instanceof Component)) { throw new AssertionFailure( "Unexpected identifier type on the referenced entity when mapping a @MapsId: " + referencedEntityName); } Component referencedComponent = (Component) referencedPersistentClass.getIdentifier(); Iterator<Property> properties = referencedComponent.getPropertyIterator(); // prepare column name structure boolean isExplicitReference = true; Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String, Ejb3JoinColumn>(joinColumns.length); for (Ejb3JoinColumn joinColumn : joinColumns) { final String referencedColumnName = joinColumn.getReferencedColumn(); if (referencedColumnName == null || BinderHelper.isEmptyAnnotationValue(referencedColumnName)) { break; } // JPA 2 requires referencedColumnNames to be case insensitive columnByReferencedName.put(referencedColumnName.toLowerCase(), joinColumn); } // try default column orientation int index = 0; if (columnByReferencedName.isEmpty()) { isExplicitReference = false; for (Ejb3JoinColumn joinColumn : joinColumns) { columnByReferencedName.put("" + index, joinColumn); index++; } index = 0; } while (properties.hasNext()) { Property referencedProperty = properties.next(); if (referencedProperty.isComposite()) { throw new AssertionFailure( "Unexpected nested component on the referenced entity when mapping a @MapsId: " + referencedEntityName); } else { Property property = new Property(); property.setName(referencedProperty.getName()); property.setNodeName(referencedProperty.getNodeName()); // FIXME set optional? // property.setOptional( property.isOptional() ); property.setPersistentClass(component.getOwner()); property.setPropertyAccessorName(referencedProperty.getPropertyAccessorName()); SimpleValue value = new SimpleValue(mappings, component.getTable()); property.setValue(value); final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue(); value.setTypeName(referencedValue.getTypeName()); value.setTypeParameters(referencedValue.getTypeParameters()); final Iterator<Column> columns = referencedValue.getColumnIterator(); if (joinColumns[0].isNameDeferred()) { joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns( referencedPersistentClass, columns, value); } else { // FIXME take care of Formula while (columns.hasNext()) { Column column = columns.next(); final Ejb3JoinColumn joinColumn; String logicalColumnName = null; if (isExplicitReference) { final String columnName = column.getName(); logicalColumnName = mappings.getLogicalColumnName(columnName, referencedPersistentClass.getTable()); // JPA 2 requires referencedColumnNames to be case insensitive joinColumn = columnByReferencedName.get(logicalColumnName.toLowerCase()); } else { joinColumn = columnByReferencedName.get("" + index); index++; } if (joinColumn == null && !joinColumns[0].isNameDeferred()) { throw new AnnotationException( isExplicitReference ? "Unable to find column reference in the @MapsId mapping: " + logicalColumnName : "Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames: " + referencedEntityName); } final String columnName = joinColumn == null || joinColumn.isNameDeferred() ? "tata_" + column.getName() : joinColumn.getName(); value.addColumn(new Column(columnName)); column.setValue(value); } } component.addProperty(property); } } }