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()); } } }
void addCollection() { Type type = propertyValue.getType(); Value value = propertyValue.getElement(); boolean oneToManyAttachedType = type instanceof BagType || type instanceof SetType || type instanceof MapType || type instanceof ListType; boolean inverseOneToMany = (value instanceof OneToMany) && (propertyValue.isInverse()); boolean owningManyToOneWithJoinTableBidirectional = (value instanceof ManyToOne) && (propertyAuditingData.getAuditMappedBy() != null); boolean fakeOneToManyBidirectional = (value instanceof OneToMany) && (propertyAuditingData.getAuditMappedBy() != null); if (oneToManyAttachedType && (inverseOneToMany || fakeOneToManyBidirectional || owningManyToOneWithJoinTableBidirectional)) { // A one-to-many relation mapped using @ManyToOne and @OneToMany(mappedBy="...") addOneToManyAttached(fakeOneToManyBidirectional); } else { // All other kinds of relations require a middle (join) table. addWithMiddleTable(); } }
private Element createMiddleEntityXml( String auditMiddleTableName, String auditMiddleEntityName, String where) { String schema = mainGenerator.getSchema( propertyAuditingData.getJoinTable().schema(), propertyValue.getCollectionTable()); String catalog = mainGenerator.getCatalog( propertyAuditingData.getJoinTable().catalog(), propertyValue.getCollectionTable()); Element middleEntityXml = MetadataTools.createEntity( xmlMappingData.newAdditionalMapping(), new AuditTableData(auditMiddleEntityName, auditMiddleTableName, schema, catalog), null); Element middleEntityXmlId = middleEntityXml.addElement("composite-id"); // If there is a where clause on the relation, adding it to the middle entity. if (where != null) { middleEntityXml.addAttribute("where", where); } middleEntityXmlId.addAttribute("name", mainGenerator.getVerEntCfg().getOriginalIdPropName()); // Adding the revision number as a foreign key to the revision info entity to the composite id // of the // middle table. mainGenerator.addRevisionInfoRelation(middleEntityXmlId); // Adding the revision type property to the entity xml. mainGenerator.addRevisionType(middleEntityXml); // All other properties should also be part of the primary key of the middle entity. return middleEntityXmlId; }
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 addMapper( CommonCollectionMapperData commonCollectionMapperData, MiddleComponentData elementComponentData, MiddleComponentData indexComponentData) { Type type = propertyValue.getType(); if (type instanceof SortedSetType) { currentMapper.addComposite( propertyAuditingData.getPropertyData(), new SortedSetCollectionMapper( commonCollectionMapperData, TreeSet.class, SortedSetProxy.class, elementComponentData, propertyValue.getComparator())); } else if (type instanceof SetType) { currentMapper.addComposite( propertyAuditingData.getPropertyData(), new BasicCollectionMapper<Set>( commonCollectionMapperData, HashSet.class, SetProxy.class, elementComponentData)); } else if (type instanceof SortedMapType) { // Indexed collection, so <code>indexComponentData</code> is not null. currentMapper.addComposite( propertyAuditingData.getPropertyData(), new SortedMapCollectionMapper( commonCollectionMapperData, TreeMap.class, SortedMapProxy.class, elementComponentData, indexComponentData, propertyValue.getComparator())); } else if (type instanceof MapType) { // Indexed collection, so <code>indexComponentData</code> is not null. currentMapper.addComposite( propertyAuditingData.getPropertyData(), new MapCollectionMapper<Map>( commonCollectionMapperData, HashMap.class, MapProxy.class, elementComponentData, indexComponentData)); } else if (type instanceof BagType) { currentMapper.addComposite( propertyAuditingData.getPropertyData(), new BasicCollectionMapper<List>( commonCollectionMapperData, ArrayList.class, ListProxy.class, elementComponentData)); } else if (type instanceof ListType) { // Indexed collection, so <code>indexComponentData</code> is not null. currentMapper.addComposite( propertyAuditingData.getPropertyData(), new ListCollectionMapper( commonCollectionMapperData, elementComponentData, indexComponentData)); } else { mainGenerator.throwUnsupportedTypeException(type, referencingEntityName, propertyName); } }
public OneToManyPersister( Collection collection, CollectionRegionAccessStrategy cacheAccessStrategy, Configuration cfg, SessionFactoryImplementor factory) throws MappingException, CacheException { super(collection, cacheAccessStrategy, cfg, factory); cascadeDeleteEnabled = collection.getKey().isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete(); keyIsNullable = collection.getKey().isNullable(); keyIsUpdateable = collection.getKey().isUpdateable(); }
private String getMiddleTableName(Collection value, String entityName) { // We check how Hibernate maps the collection. if (value.getElement() instanceof OneToMany && !value.isInverse()) { // This must be a @JoinColumn+@OneToMany mapping. Generating the table name, as Hibernate // doesn't use a // middle table for mapping this relation. return StringTools.getLastComponent(entityName) + "_" + StringTools.getLastComponent(MappingTools.getReferencedEntityName(value.getElement())); } // Hibernate uses a middle table for mapping this relation, so we get it's name directly. return value.getCollectionTable().getName(); }
private Property makeCollectionProperty( String propertyName, boolean mutable, Table table, ForeignKey fk, Collection value, boolean inverseProperty) { AssociationInfo fkei = inverseProperty ? revengStrategy.foreignKeyToInverseAssociationInfo(fk) : revengStrategy.foreignKeyToAssociationInfo(fk); String fetchMode = null; String cascade = null; boolean update = mutable; boolean insert = mutable; if (fkei != null) { cascade = fkei.getCascade(); if (cascade == null) cascade = "all"; // To ensure collections cascade to be compatible with Seam-gen and previous // behavior. if (fkei.getUpdate() != null) { update = fkei.getUpdate().booleanValue(); } if (fkei.getInsert() != null) { insert = fkei.getInsert().booleanValue(); } fetchMode = fkei.getFetch(); } if (FetchMode.JOIN.toString().equalsIgnoreCase(fetchMode)) { value.setFetchMode(FetchMode.JOIN); } else if (FetchMode.SELECT.toString().equalsIgnoreCase(fetchMode)) { value.setFetchMode(FetchMode.SELECT); } else { value.setFetchMode(FetchMode.SELECT); } return makeProperty( TableIdentifier.create(table), propertyName, value, insert, update, value.getFetchMode() != FetchMode.JOIN, cascade, null); }
/** * @param cfg * @return iterator over all the IdentifierGenerator's found in the entitymodel and return a list * of unique IdentifierGenerators * @throws MappingException */ private Iterator iterateGenerators(Configuration cfg) throws MappingException { TreeMap generators = new TreeMap(); String defaultCatalog = getSettings().getDefaultCatalogName(); String defaultSchema = getSettings().getDefaultSchemaName(); Iterator iter = cfg.getClassMappings(); while (iter.hasNext()) { PersistentClass pc = (PersistentClass) iter.next(); if (!pc.isInherited()) { IdentifierGenerator ig = pc.getIdentifier() .createIdentifierGenerator( cfg.getIdentifierGeneratorFactory(), dialect, defaultCatalog, defaultSchema, (RootClass) pc); if (ig instanceof PersistentIdentifierGenerator) { generators.put(((PersistentIdentifierGenerator) ig).generatorKey(), ig); } } } iter = getConfiguration().getCollectionMappings(); while (iter.hasNext()) { Collection collection = (Collection) iter.next(); if (collection.isIdentified()) { IdentifierGenerator ig = ((IdentifierCollection) collection) .getIdentifier() .createIdentifierGenerator( getConfiguration().getIdentifierGeneratorFactory(), dialect, defaultCatalog, defaultSchema, null); if (ig instanceof PersistentIdentifierGenerator) { generators.put(((PersistentIdentifierGenerator) ig).generatorKey(), ig); } } } return generators.values().iterator(); }
@Test public void testWithJpaCompliantNamingStrategy() throws Exception { Metadata metadata = new MetadataSources(serviceRegistry) .addAnnotatedClass(A.class) .addAnnotatedClass(AddressEntry.class) .getMetadataBuilder() .applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE) .build(); Collection collectionBinding = metadata.getCollectionBinding(A.class.getName() + ".address"); assertEquals( "Expecting A#address collection table name (implicit) to be [A_address] per JPA spec (section 11.1.8)", "A_ADDRESS", collectionBinding.getCollectionTable().getQuotedName().toUpperCase(Locale.ROOT)); }
/** * @param mainGenerator Main generator, giving access to configuration and the basic mapper. * @param propertyValue Value of the collection, as mapped by Hibernate. * @param currentMapper Mapper, to which the appropriate {@link * org.hibernate.envers.entities.mapper.PropertyMapper} will be added. * @param referencingEntityName Name of the entity that owns this collection. * @param xmlMappingData In case this collection requires a middle table, additional mapping * documents will be created using this object. * @param propertyAuditingData Property auditing (meta-)data. Among other things, holds the name * of the property that references the collection in the referencing entity, the user data for * middle (join) table and the value of the <code>@MapKey</code> annotation, if there was one. */ public CollectionMetadataGenerator( AuditMetadataGenerator mainGenerator, Collection propertyValue, CompositeMapperBuilder currentMapper, String referencingEntityName, EntityXmlMappingData xmlMappingData, PropertyAuditingData propertyAuditingData) { this.mainGenerator = mainGenerator; this.propertyValue = propertyValue; this.currentMapper = currentMapper; this.referencingEntityName = referencingEntityName; this.xmlMappingData = xmlMappingData; this.propertyAuditingData = propertyAuditingData; this.propertyName = propertyAuditingData.getName(); referencingEntityConfiguration = mainGenerator.getEntitiesConfigurations().get(referencingEntityName); if (referencingEntityConfiguration == null) { throw new MappingException( "Unable to read auditing configuration for " + referencingEntityName + "!"); } referencedEntityName = MappingTools.getReferencedEntityName(propertyValue.getElement()); }
private String getMappedBy(Collection collectionValue) { PersistentClass referencedClass = null; if (collectionValue.getElement() instanceof OneToMany) { OneToMany oneToManyValue = (OneToMany) collectionValue.getElement(); referencedClass = oneToManyValue.getAssociatedClass(); } else if (collectionValue.getElement() instanceof ManyToOne) { // Case for bi-directional relation with @JoinTable on the owning @ManyToOne side. ManyToOne manyToOneValue = (ManyToOne) collectionValue.getElement(); referencedClass = manyToOneValue.getMappings().getClass(manyToOneValue.getReferencedEntityName()); } // If there's an @AuditMappedBy specified, returning it directly. String auditMappedBy = propertyAuditingData.getAuditMappedBy(); if (auditMappedBy != null) { return auditMappedBy; } // searching in referenced class String mappedBy = this.searchMappedBy(referencedClass, collectionValue); if (mappedBy == null) { LOG.debugf( "Going to search the mapped by attribute for %s in superclasses of entity: %s", propertyName, referencedClass.getClassName()); PersistentClass tempClass = referencedClass; while ((mappedBy == null) && (tempClass.getSuperclass() != null)) { LOG.debugf("Searching in superclass: %s", tempClass.getSuperclass().getClassName()); mappedBy = this.searchMappedBy(tempClass.getSuperclass(), collectionValue); tempClass = tempClass.getSuperclass(); } } if (mappedBy == null) { throw new MappingException( "Unable to read the mapped by attribute for " + propertyName + " in " + referencedClass.getClassName() + "!"); } return mappedBy; }
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 void storeMiddleEntityRelationInformation(String mappedBy) { // Only if this is a relation (when there is a referenced entity). if (referencedEntityName != null) { if (propertyValue.isInverse()) { referencingEntityConfiguration.addToManyMiddleNotOwningRelation( propertyName, mappedBy, referencedEntityName); } else { referencingEntityConfiguration.addToManyMiddleRelation(propertyName, referencedEntityName); } } }
public static void bindCollectionSecondPass( Collection collection, java.util.Map persistentClasses, Mappings mappings, java.util.Map inheritedMetas) throws MappingException { if (collection.isOneToMany()) { OneToMany oneToMany = (OneToMany) collection.getElement(); PersistentClass persistentClass = mappings.getClass(oneToMany.getReferencedEntityName()); if (persistentClass == null) throw new MappingException( "Association " + collection.getRole() + " references unmapped class: " + oneToMany.getReferencedEntityName()); oneToMany.setAssociatedClass(persistentClass); // Child } }
@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 void bindIndex(final ExtendedMappings mappings) { if (indexColumn.isImplicit() == false) { PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder( this.collection, IndexedCollection.DEFAULT_INDEX_COLUMN_NAME, (XClass) null, (XProperty) null); List list = (List) this.collection; if (!list.isOneToMany()) indexColumn.forceNotNull(); indexColumn.setPropertyHolder(valueHolder); SimpleValueBinder value = new SimpleValueBinder(); value.setColumns(new Ejb3Column[] {indexColumn}); value.setExplicitType("integer"); value.setMappings(mappings); SimpleValue indexValue = value.make(); indexColumn.linkWithValue(indexValue); list.setIndex(indexValue); list.setBaseIndex(indexColumn.getBase()); if (list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse()) { String entityName = ((OneToMany) list.getElement()).getReferencedEntityName(); PersistentClass referenced = mappings.getClass(entityName); IndexBackref ib = new IndexBackref(); ib.setName('_' + propertyName + "IndexBackref"); ib.setUpdateable(false); ib.setSelectable(false); ib.setCollectionRole(list.getRole()); ib.setEntityName(list.getOwner().getEntityName()); ib.setValue(list.getIndex()); referenced.addProperty(ib); } } else { Collection coll = this.collection; throw new AnnotationException( "List/array has to be annotated with an @IndexColumn: " + coll.getRole()); } }
public void doSecondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas) throws MappingException { if (log.isDebugEnabled()) log.debug("Second pass for collection: " + collection.getRole()); secondPass(persistentClasses, inheritedMetas); collection.createAllKeys(); if (log.isDebugEnabled()) { String msg = "Mapped collection key: " + columns(collection.getKey()); if (collection.isIndexed()) msg += ", index: " + columns(((IndexedCollection) collection).getIndex()); if (collection.isOneToMany()) { msg += ", one-to-many: " + ((OneToMany) collection.getElement()).getReferencedEntityName(); } else { msg += ", element: " + columns(collection.getElement()); } log.debug(msg); } }
public void doSecondPass(java.util.Map persistentClasses) throws MappingException { if (log.isDebugEnabled()) log.debug("Second pass for collection: " + collection.getRole()); secondPass( persistentClasses, localInheritedMetas); // using local since the inheritedMetas at this point is not the // correct map since it is always the empty map collection.createAllKeys(); if (log.isDebugEnabled()) { String msg = "Mapped collection key: " + columns(collection.getKey()); if (collection.isIndexed()) msg += ", index: " + columns(((IndexedCollection) collection).getIndex()); if (collection.isOneToMany()) { msg += ", one-to-many: " + ((OneToMany) collection.getElement()).getReferencedEntityName(); } else { msg += ", element: " + columns(collection.getElement()); } log.debug(msg); } }
/** * Here is most of the nuts and bolts of this factory, where we interpret the known JPA metadata * against the known Hibernate metadata and build a descriptor for the attribute. * * @param attributeContext The attribute to be described * @param memberResolver Strategy for how to resolve the member defining the attribute. * @param <X> The owner type * @param <Y> The attribute type * @return The attribute description */ @SuppressWarnings({"unchecked"}) private <X, Y> AttributeMetadata<X, Y> determineAttributeMetadata( AttributeContext<X> attributeContext, MemberResolver memberResolver) { LOG.trace( "Starting attribute metadata determination [" + attributeContext.getPropertyMapping().getName() + "]"); final Member member = memberResolver.resolveMember(attributeContext); LOG.trace(" Determined member [" + member + "]"); final Value value = attributeContext.getPropertyMapping().getValue(); final org.hibernate.type.Type type = value.getType(); LOG.trace( " Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]"); if (type.isAnyType()) { // ANY mappings are currently not supported in the JPA metamodel; see HHH-6589 if (context.isIgnoreUnsupported()) { return null; } else { throw new UnsupportedOperationException("ANY not supported"); } } else if (type.isAssociationType()) { // collection or entity if (type.isEntityType()) { // entity return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, determineSingularAssociationAttributeType(member)); } // collection if (value instanceof Collection) { final Collection collValue = (Collection) value; final Value elementValue = collValue.getElement(); final org.hibernate.type.Type elementType = elementValue.getType(); // First, determine the type of the elements and use that to help determine the // collection type) final Attribute.PersistentAttributeType elementPersistentAttributeType; final Attribute.PersistentAttributeType persistentAttributeType; if (elementType.isAnyType()) { throw new UnsupportedOperationException("collection of any not supported yet"); } final boolean isManyToMany = isManyToMany(member); if (elementValue instanceof Component) { elementPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED; persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION; } else if (elementType.isAssociationType()) { elementPersistentAttributeType = isManyToMany ? Attribute.PersistentAttributeType.MANY_TO_MANY : Attribute.PersistentAttributeType.ONE_TO_MANY; persistentAttributeType = elementPersistentAttributeType; } else { elementPersistentAttributeType = Attribute.PersistentAttributeType.BASIC; persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION; } final Attribute.PersistentAttributeType keyPersistentAttributeType; // Finally, we determine the type of the map key (if needed) if (value instanceof Map) { final Value keyValue = ((Map) value).getIndex(); final org.hibernate.type.Type keyType = keyValue.getType(); if (keyType.isAnyType()) throw new UnsupportedOperationException("collection of any not supported yet"); if (keyValue instanceof Component) keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED; else if (keyType.isAssociationType()) keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE; else keyPersistentAttributeType = Attribute.PersistentAttributeType.BASIC; } else keyPersistentAttributeType = null; return new PluralAttributeMetadataImpl( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, persistentAttributeType, elementPersistentAttributeType, keyPersistentAttributeType); } else if (value instanceof OneToMany) { // TODO : is this even possible??? Really OneToMany should be describing the // element value within a o.h.mapping.Collection (see logic branch above) throw new IllegalArgumentException("HUH???"); // final boolean isManyToMany = isManyToMany( member ); // //one to many with FK => entity // return new PluralAttributeMetadataImpl( // attributeContext.getPropertyMapping(), // attributeContext.getOwnerType(), // member, // isManyToMany // ? Attribute.PersistentAttributeType.MANY_TO_MANY // : Attribute.PersistentAttributeType.ONE_TO_MANY // value, // AttributeContext.TypeStatus.ENTITY, // Attribute.PersistentAttributeType.ONE_TO_MANY, // null, null, null // ); } } else if (attributeContext.getPropertyMapping().isComposite()) { // component return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.EMBEDDED); } else { // basic type return new SingularAttributeMetadataImpl<X, Y>( attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.BASIC); } throw new UnsupportedOperationException( "oops, we are missing something: " + attributeContext.getPropertyMapping()); }
/** * @param rc * @param processed * @param table * @param object */ private Property bindOneToMany( PersistentClass rc, ForeignKey foreignKey, Set processed, Mapping mapping) { Table collectionTable = foreignKey.getTable(); // Collection collection = new org.hibernate.mapping.Set(rc); // MASTER TODO: allow overriding // collection type Collection collection = new org.hibernate.mapping.List(rc); // MASTER TODO: allow overriding collection type collection.setCollectionTable(collectionTable); // CHILD+ boolean manyToMany = revengStrategy.isManyToManyTable(collectionTable); if (manyToMany) { // log.debug("Rev.eng said here is a many-to-many"); // TODO: handle "the other side should influence the name" } if (manyToMany) { ManyToOne element = new ManyToOne(collection.getCollectionTable()); // TODO: find the other foreignkey and choose the other side. Iterator foreignKeyIterator = foreignKey.getTable().getForeignKeyIterator(); List keys = new ArrayList(); while (foreignKeyIterator.hasNext()) { Object next = foreignKeyIterator.next(); if (next != foreignKey) { keys.add(next); } } if (keys.size() > 1) { throw new JDBCBinderException( "more than one other foreign key to choose from!"); // todo: handle better ? } ForeignKey fk = (ForeignKey) keys.get(0); String tableToClassName = bindCollection(rc, foreignKey, fk, collection); element.setReferencedEntityName(tableToClassName); element.addColumn(fk.getColumn(0)); collection.setElement(element); } else { String tableToClassName = bindCollection(rc, foreignKey, null, collection); OneToMany oneToMany = new OneToMany(collection.getOwner()); oneToMany.setReferencedEntityName(tableToClassName); // Child mappings.addSecondPass(new JDBCCollectionSecondPass(mappings, collection)); collection.setElement(oneToMany); } // bind keyvalue KeyValue referencedKeyValue; String propRef = collection.getReferencedPropertyName(); if (propRef == null) { referencedKeyValue = collection.getOwner().getIdentifier(); } else { referencedKeyValue = (KeyValue) collection.getOwner().getProperty(propRef).getValue(); } SimpleValue keyValue = new DependantValue(collectionTable, referencedKeyValue); // keyValue.setForeignKeyName("none"); // Avoid creating the foreignkey // key.setCascadeDeleteEnabled( "cascade".equals( subnode.attributeValue("on-delete") ) ); Iterator columnIterator = foreignKey.getColumnIterator(); while (columnIterator.hasNext()) { Column fkcolumn = (Column) columnIterator.next(); if (fkcolumn.getSqlTypeCode() != null) { // TODO: user defined foreign ref columns does not have a type set. guessAndAlignType( collectionTable, fkcolumn, mapping, false); // needed to ensure foreign key columns has same type as the "property" column. } keyValue.addColumn(fkcolumn); } collection.setKey(keyValue); mappings.addCollection(collection); return makeCollectionProperty( StringHelper.unqualify(collection.getRole()), true, rc.getTable(), foreignKey, collection, true); // return makeProperty(TableIdentifier.create( rc.getTable() ), StringHelper.unqualify( // collection.getRole() ), collection, true, true, true, "none", null); // TODO: cascade isn't // all by default }
private String bindCollection( PersistentClass rc, ForeignKey fromForeignKey, ForeignKey toForeignKey, Collection collection) { ForeignKey targetKey = fromForeignKey; String collectionRole = null; boolean collectionLazy = false; boolean collectionInverse = false; TableIdentifier foreignKeyTable = null; String tableToClassName; if (toForeignKey != null) { targetKey = toForeignKey; } boolean uniqueReference = isUniqueReference(targetKey); // TODO: need to look one step further for many-to-many! foreignKeyTable = TableIdentifier.create(targetKey.getTable()); TableIdentifier foreignKeyReferencedTable = TableIdentifier.create(targetKey.getReferencedTable()); if (toForeignKey == null) { collectionRole = revengStrategy.foreignKeyToCollectionName( fromForeignKey.getName(), foreignKeyTable, fromForeignKey.getColumns(), foreignKeyReferencedTable, fromForeignKey.getReferencedColumns(), uniqueReference); tableToClassName = revengStrategy.tableToClassName(foreignKeyTable); } else { collectionRole = revengStrategy.foreignKeyToManyToManyName( fromForeignKey, TableIdentifier.create(fromForeignKey.getTable()), toForeignKey, uniqueReference); tableToClassName = revengStrategy.tableToClassName(foreignKeyReferencedTable); } collectionInverse = revengStrategy.isForeignKeyCollectionInverse( targetKey.getName(), foreignKeyTable, targetKey.getColumns(), foreignKeyReferencedTable, targetKey.getReferencedColumns()); collectionLazy = revengStrategy.isForeignKeyCollectionLazy( targetKey.getName(), foreignKeyTable, targetKey.getColumns(), foreignKeyReferencedTable, targetKey.getReferencedColumns()); collectionRole = makeUnique(rc, collectionRole); String fullRolePath = StringHelper.qualify(rc.getEntityName(), collectionRole); if (mappings.getCollection(fullRolePath) != null) { log.debug(fullRolePath + " found twice!"); } collection.setRole(fullRolePath); // Master.setOfChildren+ collection.setInverse(collectionInverse); // TODO: allow overriding this collection.setLazy(collectionLazy); collection.setFetchMode(FetchMode.SELECT); return tableToClassName; }
public SessionFactoryImpl( Configuration cfg, Mapping mapping, Settings settings, EventListeners listeners, SessionFactoryObserver observer) throws HibernateException { log.info("building session factory"); Statistics concurrentStatistics = null; try { Class concurrentStatsClass = ReflectHelper.classForName("org.hibernate.stat.ConcurrentStatisticsImpl"); Constructor constructor = concurrentStatsClass.getConstructor(new Class[] {SessionFactoryImplementor.class}); concurrentStatistics = (Statistics) constructor.newInstance(new Object[] {this}); log.trace("JDK 1.5 concurrent classes present"); } catch (NoClassDefFoundError noJava5) { log.trace("JDK 1.5 concurrent classes missing"); } catch (Exception noJava5) { log.trace("JDK 1.5 concurrent classes missing"); } if (concurrentStatistics != null) { this.statistics = concurrentStatistics; } else { this.statistics = new StatisticsImpl(this); } if (log.isTraceEnabled()) { log.trace("Statistics initialized with " + statistics.getClass().getName()); } this.properties = new Properties(); this.properties.putAll(cfg.getProperties()); this.interceptor = cfg.getInterceptor(); this.settings = settings; this.sqlFunctionRegistry = new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions()); this.eventListeners = listeners; this.observer = observer != null ? observer : new SessionFactoryObserver() { public void sessionFactoryCreated(SessionFactory factory) {} public void sessionFactoryClosed(SessionFactory factory) {} }; this.filters = new HashMap(); this.filters.putAll(cfg.getFilterDefinitions()); if (log.isDebugEnabled()) { log.debug("Session factory constructed with filter configurations : " + filters); } if (log.isDebugEnabled()) { log.debug("instantiating session factory with properties: " + properties); } // Caches settings.getRegionFactory().start(settings, properties); // Generators: identifierGenerators = new HashMap(); Iterator classes = cfg.getClassMappings(); while (classes.hasNext()) { PersistentClass model = (PersistentClass) classes.next(); if (!model.isInherited()) { IdentifierGenerator generator = model .getIdentifier() .createIdentifierGenerator( cfg.getIdentifierGeneratorFactory(), settings.getDialect(), settings.getDefaultCatalogName(), settings.getDefaultSchemaName(), (RootClass) model); identifierGenerators.put(model.getEntityName(), generator); } } /////////////////////////////////////////////////////////////////////// // Prepare persisters and link them up with their cache // region/access-strategy final String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + "."; entityPersisters = new HashMap(); Map entityAccessStrategies = new HashMap(); Map classMeta = new HashMap(); classes = cfg.getClassMappings(); while (classes.hasNext()) { final PersistentClass model = (PersistentClass) classes.next(); model.prepareTemporaryTables(mapping, settings.getDialect()); final String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName(); // cache region is defined by the root-class in the hierarchy... EntityRegionAccessStrategy accessStrategy = (EntityRegionAccessStrategy) entityAccessStrategies.get(cacheRegionName); if (accessStrategy == null && settings.isSecondLevelCacheEnabled()) { final AccessType accessType = AccessType.parse(model.getCacheConcurrencyStrategy()); if (accessType != null) { log.trace("Building cache for entity data [" + model.getEntityName() + "]"); EntityRegion entityRegion = settings .getRegionFactory() .buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode(model)); accessStrategy = entityRegion.buildAccessStrategy(accessType); entityAccessStrategies.put(cacheRegionName, accessStrategy); allCacheRegions.put(cacheRegionName, entityRegion); } } EntityPersister cp = PersisterFactory.createClassPersister(model, accessStrategy, this, mapping); entityPersisters.put(model.getEntityName(), cp); classMeta.put(model.getEntityName(), cp.getClassMetadata()); } classMetadata = Collections.unmodifiableMap(classMeta); Map tmpEntityToCollectionRoleMap = new HashMap(); collectionPersisters = new HashMap(); Iterator collections = cfg.getCollectionMappings(); while (collections.hasNext()) { Collection model = (Collection) collections.next(); final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName(); final AccessType accessType = AccessType.parse(model.getCacheConcurrencyStrategy()); CollectionRegionAccessStrategy accessStrategy = null; if (accessType != null && settings.isSecondLevelCacheEnabled()) { log.trace("Building cache for collection data [" + model.getRole() + "]"); CollectionRegion collectionRegion = settings .getRegionFactory() .buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode(model)); accessStrategy = collectionRegion.buildAccessStrategy(accessType); entityAccessStrategies.put(cacheRegionName, accessStrategy); allCacheRegions.put(cacheRegionName, collectionRegion); } CollectionPersister persister = PersisterFactory.createCollectionPersister(cfg, model, accessStrategy, this); collectionPersisters.put(model.getRole(), persister.getCollectionMetadata()); Type indexType = persister.getIndexType(); if (indexType != null && indexType.isAssociationType() && !indexType.isAnyType()) { String entityName = ((AssociationType) indexType).getAssociatedEntityName(this); Set roles = (Set) tmpEntityToCollectionRoleMap.get(entityName); if (roles == null) { roles = new HashSet(); tmpEntityToCollectionRoleMap.put(entityName, roles); } roles.add(persister.getRole()); } Type elementType = persister.getElementType(); if (elementType.isAssociationType() && !elementType.isAnyType()) { String entityName = ((AssociationType) elementType).getAssociatedEntityName(this); Set roles = (Set) tmpEntityToCollectionRoleMap.get(entityName); if (roles == null) { roles = new HashSet(); tmpEntityToCollectionRoleMap.put(entityName, roles); } roles.add(persister.getRole()); } } collectionMetadata = Collections.unmodifiableMap(collectionPersisters); Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator(); while (itr.hasNext()) { final Map.Entry entry = (Map.Entry) itr.next(); entry.setValue(Collections.unmodifiableSet((Set) entry.getValue())); } collectionRolesByEntityParticipant = Collections.unmodifiableMap(tmpEntityToCollectionRoleMap); // Named Queries: namedQueries = new HashMap(cfg.getNamedQueries()); namedSqlQueries = new HashMap(cfg.getNamedSQLQueries()); sqlResultSetMappings = new HashMap(cfg.getSqlResultSetMappings()); imports = new HashMap(cfg.getImports()); // after *all* persisters and named queries are registered Iterator iter = entityPersisters.values().iterator(); while (iter.hasNext()) { final EntityPersister persister = ((EntityPersister) iter.next()); persister.postInstantiate(); registerEntityNameResolvers(persister); } iter = collectionPersisters.values().iterator(); while (iter.hasNext()) { final CollectionPersister persister = ((CollectionPersister) iter.next()); persister.postInstantiate(); } // JNDI + Serialization: name = settings.getSessionFactoryName(); try { uuid = (String) UUID_GENERATOR.generate(null, null); } catch (Exception e) { throw new AssertionFailure("Could not generate UUID"); } SessionFactoryObjectFactory.addInstance(uuid, name, this, properties); log.debug("instantiated session factory"); if (settings.isAutoCreateSchema()) { new SchemaExport(cfg, settings).create(false, true); } if (settings.isAutoUpdateSchema()) { new SchemaUpdate(cfg, settings).execute(false, true); } if (settings.isAutoValidateSchema()) { new SchemaValidator(cfg, settings).validate(); } if (settings.isAutoDropSchema()) { schemaExport = new SchemaExport(cfg, settings); } if (settings.getTransactionManagerLookup() != null) { log.debug("obtaining JTA TransactionManager"); transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties); } else { if (settings.getTransactionFactory().isTransactionManagerRequired()) { throw new HibernateException( "The chosen transaction strategy requires access to the JTA TransactionManager"); } transactionManager = null; } currentSessionContext = buildCurrentSessionContext(); if (settings.isQueryCacheEnabled()) { updateTimestampsCache = new UpdateTimestampsCache(settings, properties); queryCache = settings .getQueryCacheFactory() .getQueryCache(null, updateTimestampsCache, settings, properties); queryCaches = new HashMap(); allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion()); allCacheRegions.put(queryCache.getRegion().getName(), queryCache.getRegion()); } else { updateTimestampsCache = null; queryCache = null; queryCaches = null; } // checking for named queries if (settings.isNamedQueryStartupCheckingEnabled()) { Map errors = checkNamedQueries(); if (!errors.isEmpty()) { Set keys = errors.keySet(); StringBuffer failingQueries = new StringBuffer("Errors in named queries: "); for (Iterator iterator = keys.iterator(); iterator.hasNext(); ) { String queryName = (String) iterator.next(); HibernateException e = (HibernateException) errors.get(queryName); failingQueries.append(queryName); if (iterator.hasNext()) { failingQueries.append(", "); } log.error("Error in named query: " + queryName, e); } throw new HibernateException(failingQueries.toString()); } } // stats getStatistics().setStatisticsEnabled(settings.isStatisticsEnabled()); // EntityNotFoundDelegate EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate(); if (entityNotFoundDelegate == null) { entityNotFoundDelegate = new EntityNotFoundDelegate() { public void handleEntityNotFound(String entityName, Serializable id) { throw new ObjectNotFoundException(id, entityName); } public boolean isEntityNotFoundException(RuntimeException exception) { return ObjectNotFoundException.class.isInstance(exception); } }; } this.entityNotFoundDelegate = entityNotFoundDelegate; // this needs to happen after persisters are all ready to go... this.fetchProfiles = new HashMap(); itr = cfg.iterateFetchProfiles(); while (itr.hasNext()) { final org.hibernate.mapping.FetchProfile mappingProfile = (org.hibernate.mapping.FetchProfile) itr.next(); final FetchProfile fetchProfile = new FetchProfile(mappingProfile.getName()); Iterator fetches = mappingProfile.getFetches().iterator(); while (fetches.hasNext()) { final org.hibernate.mapping.FetchProfile.Fetch mappingFetch = (org.hibernate.mapping.FetchProfile.Fetch) fetches.next(); // resolve the persister owning the fetch final String entityName = getImportedClassName(mappingFetch.getEntity()); final EntityPersister owner = (EntityPersister) (entityName == null ? null : entityPersisters.get(entityName)); if (owner == null) { throw new HibernateException( "Unable to resolve entity reference [" + mappingFetch.getEntity() + "] in fetch profile [" + fetchProfile.getName() + "]"); } // validate the specified association fetch Type associationType = owner.getPropertyType(mappingFetch.getAssociation()); if (associationType == null || !associationType.isAssociationType()) { throw new HibernateException( "Fetch profile [" + fetchProfile.getName() + "] specified an invalid association"); } // resolve the style final Fetch.Style fetchStyle = Fetch.Style.parse(mappingFetch.getStyle()); // then construct the fetch instance... fetchProfile.addFetch(new Association(owner, mappingFetch.getAssociation()), fetchStyle); ((Loadable) owner).registerAffectingFetchProfile(fetchProfile.getName()); } fetchProfiles.put(fetchProfile.getName(), fetchProfile); } this.observer.sessionFactoryCreated(this); }
@Override public Class<? extends CollectionPersister> getCollectionPersisterClass(Collection metadata) { return metadata.isOneToMany() ? oneToManyPersister() : basicCollectionPersister(); }
@SuppressWarnings({"unchecked"}) private void addWithMiddleTable() { LOG.debugf( "Adding audit mapping for property %s.%s: collection with a join table", referencingEntityName, propertyName); // Generating the name of the middle table String auditMiddleTableName; String auditMiddleEntityName; if (!StringTools.isEmpty(propertyAuditingData.getJoinTable().name())) { auditMiddleTableName = propertyAuditingData.getJoinTable().name(); auditMiddleEntityName = propertyAuditingData.getJoinTable().name(); } else { String middleTableName = getMiddleTableName(propertyValue, referencingEntityName); auditMiddleTableName = mainGenerator.getVerEntCfg().getAuditTableName(null, middleTableName); auditMiddleEntityName = mainGenerator.getVerEntCfg().getAuditEntityName(middleTableName); } LOG.debugf("Using join table name: %s", auditMiddleTableName); // Generating the XML mapping for the middle entity, only if the relation isn't inverse. // If the relation is inverse, will be later checked by comparing middleEntityXml with null. Element middleEntityXml; if (!propertyValue.isInverse()) { // Generating a unique middle entity name auditMiddleEntityName = mainGenerator.getAuditEntityNameRegister().createUnique(auditMiddleEntityName); // Registering the generated name mainGenerator.getAuditEntityNameRegister().register(auditMiddleEntityName); middleEntityXml = createMiddleEntityXml( auditMiddleTableName, auditMiddleEntityName, propertyValue.getWhere()); } else { middleEntityXml = null; } // ****** // Generating the mapping for the referencing entity (it must be an entity). // ****** // Getting the id-mapping data of the referencing entity (the entity that "owns" this // collection). IdMappingData referencingIdMapping = referencingEntityConfiguration.getIdMappingData(); // Only valid for an inverse relation; null otherwise. String mappedBy; // The referencing prefix is always for a related entity. So it has always the "_" at the end // added. String referencingPrefixRelated; String referencedPrefix; if (propertyValue.isInverse()) { // If the relation is inverse, then referencedEntityName is not null. mappedBy = getMappedBy( propertyValue.getCollectionTable(), mainGenerator.getCfg().getClassMapping(referencedEntityName)); referencingPrefixRelated = mappedBy + "_"; referencedPrefix = StringTools.getLastComponent(referencedEntityName); } else { mappedBy = null; referencingPrefixRelated = StringTools.getLastComponent(referencingEntityName) + "_"; referencedPrefix = referencedEntityName == null ? "element" : propertyName; } // Storing the id data of the referencing entity: original mapper, prefixed mapper and entity // name. MiddleIdData referencingIdData = createMiddleIdData(referencingIdMapping, referencingPrefixRelated, referencingEntityName); // Creating a query generator builder, to which additional id data will be added, in case this // collection // references some entities (either from the element or index). At the end, this will be used to // build // a query generator to read the raw data collection from the middle table. QueryGeneratorBuilder queryGeneratorBuilder = new QueryGeneratorBuilder( mainGenerator.getGlobalCfg(), mainGenerator.getVerEntCfg(), mainGenerator.getAuditStrategy(), referencingIdData, auditMiddleEntityName); // Adding the XML mapping for the referencing entity, if the relation isn't inverse. if (middleEntityXml != null) { // Adding related-entity (in this case: the referencing's entity id) id mapping to the xml. addRelatedToXmlMapping( middleEntityXml, referencingPrefixRelated, MetadataTools.getColumnNameIterator(propertyValue.getKey().getColumnIterator()), referencingIdMapping); } // ****** // Generating the element mapping. // ****** MiddleComponentData elementComponentData = addValueToMiddleTable( propertyValue.getElement(), middleEntityXml, queryGeneratorBuilder, referencedPrefix, propertyAuditingData.getJoinTable().inverseJoinColumns()); // ****** // Generating the index mapping, if an index exists. // ****** MiddleComponentData indexComponentData = addIndex(middleEntityXml, queryGeneratorBuilder); // ****** // Generating the property mapper. // ****** // Building the query generator. RelationQueryGenerator queryGenerator = queryGeneratorBuilder.build(elementComponentData, indexComponentData); // Creating common data CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData( mainGenerator.getVerEntCfg(), auditMiddleEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator); // Checking the type of the collection and adding an appropriate mapper. addMapper(commonCollectionMapperData, elementComponentData, indexComponentData); // ****** // Storing information about this relation. // ****** storeMiddleEntityRelationInformation(mappedBy); }
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; } }