/** Constructor */
 public FeatureMapEntryInstantiator(PersistentClass pc) {
   AssertUtil.assertTrue(
       pc.getEntityName() + " does not have a meta attribute",
       pc.getMetaAttribute(HbMapperConstants.FEATUREMAP_META) != null);
   log.debug("Creating fme instantiator for " + pc.getEntityName());
   proxyInterface = pc.getProxyInterface();
   persistentClass = pc;
 }
 public DynamicMapInstantiator(PersistentClass mappingInfo) {
   this.entityName = mappingInfo.getEntityName();
   isInstanceEntityNames.add(entityName);
   if (mappingInfo.hasSubclasses()) {
     Iterator itr = mappingInfo.getSubclassClosureIterator();
     while (itr.hasNext()) {
       final PersistentClass subclassInfo = (PersistentClass) itr.next();
       isInstanceEntityNames.add(subclassInfo.getEntityName());
     }
   }
 }
Ejemplo n.º 3
0
 public void popEntityWorkedOn(PersistentClass persistentClass) {
   final PersistentClass stackTop =
       stackOfPersistentClassesBeingProcessed.remove(
           stackOfPersistentClassesBeingProcessed.size() - 1);
   if (stackTop != persistentClass) {
     throw new AssertionFailure(
         "Inconsistent popping: "
             + persistentClass.getEntityName()
             + " instead of "
             + stackTop.getEntityName());
   }
 }
 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());
     }
   }
 }
Ejemplo n.º 5
0
 /*package*/ void registerEntityType(
     PersistentClass persistentClass, EntityTypeImpl<?> entityType) {
   entityTypes.put(entityType.getBindableJavaType(), entityType);
   entityTypesByEntityName.put(persistentClass.getEntityName(), entityType);
   entityTypesByPersistentClass.put(persistentClass, entityType);
   orderedMappings.add(persistentClass);
 }
 @Override
 public Class<? extends EntityPersister> getEntityPersisterClass(PersistentClass metadata) {
   // todo : make sure this is based on an attribute kept on the metamodel in the new code, not the
   // concrete PersistentClass impl found!
   if (RootClass.class.isInstance(metadata)) {
     if (metadata.hasSubclasses()) {
       // If the class has children, we need to find of which kind
       metadata = (PersistentClass) metadata.getDirectSubclasses().next();
     } else {
       return singleTableEntityPersister();
     }
   }
   if (JoinedSubclass.class.isInstance(metadata)) {
     return joinedSubclassEntityPersister();
   } else if (UnionSubclass.class.isInstance(metadata)) {
     return unionSubclassEntityPersister();
   } else if (SingleTableSubclass.class.isInstance(metadata)) {
     return singleTableEntityPersister();
   } else {
     throw new UnknownPersisterException(
         "Could not determine persister implementation for entity ["
             + metadata.getEntityName()
             + "]");
   }
 }
  public static GroovyAwareJavassistProxyFactory buildProxyFactory(
      PersistentClass persistentClass) {
    GroovyAwareJavassistProxyFactory proxyFactory = new GroovyAwareJavassistProxyFactory();

    @SuppressWarnings("unchecked")
    Set<Class<HibernateProxy>> proxyInterfaces = new HashSet<Class<HibernateProxy>>();
    proxyInterfaces.add(HibernateProxy.class);

    final Class<?> javaClass = persistentClass.getMappedClass();
    final Property identifierProperty = persistentClass.getIdentifierProperty();
    final Method idGetterMethod =
        identifierProperty != null ? identifierProperty.getGetter(javaClass).getMethod() : null;
    final Method idSetterMethod =
        identifierProperty != null ? identifierProperty.getSetter(javaClass).getMethod() : null;
    final Type identifierType =
        persistentClass.hasEmbeddedIdentifier() ? persistentClass.getIdentifier().getType() : null;

    try {
      proxyFactory.postInstantiate(
          persistentClass.getEntityName(),
          javaClass,
          proxyInterfaces,
          idGetterMethod,
          idSetterMethod,
          identifierType instanceof CompositeType ? (CompositeType) identifierType : null);
    } catch (HibernateException e) {
      LOG.warn("Cannot instantiate proxy factory: " + e.getMessage());
      return null;
    }

    return proxyFactory;
  }
Ejemplo n.º 8
0
  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;
    }
  }
 /** Instantiates using the EFactory */
 public Object instantiate() {
   final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
   fme.setEntityName(persistentClass.getEntityName());
   return fme;
 }
Ejemplo n.º 10
0
  @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);
    }
  }
Ejemplo n.º 11
0
  public EntityMetamodel(
      PersistentClass persistentClass,
      AbstractEntityPersister persister,
      SessionFactoryImplementor sessionFactory) {
    this.sessionFactory = sessionFactory;
    this.persister = persister;

    name = persistentClass.getEntityName();
    rootName = persistentClass.getRootClass().getEntityName();
    entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne(name);

    identifierAttribute =
        PropertyFactory.buildIdentifierAttribute(
            persistentClass, sessionFactory.getIdentifierGenerator(rootName));

    versioned = persistentClass.isVersioned();

    instrumentationMetadata =
        persistentClass.hasPojoRepresentation()
            ? Environment.getBytecodeProvider()
                .getEntityInstrumentationMetadata(persistentClass.getMappedClass())
            : new NonPojoInstrumentationMetadata(persistentClass.getEntityName());

    boolean hasLazy = false;

    propertySpan = persistentClass.getPropertyClosureSpan();
    properties = new NonIdentifierAttribute[propertySpan];
    List<Integer> naturalIdNumbers = new ArrayList<Integer>();
    // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    propertyNames = new String[propertySpan];
    propertyTypes = new Type[propertySpan];
    propertyUpdateability = new boolean[propertySpan];
    propertyInsertability = new boolean[propertySpan];
    nonlazyPropertyUpdateability = new boolean[propertySpan];
    propertyCheckability = new boolean[propertySpan];
    propertyNullability = new boolean[propertySpan];
    propertyVersionability = new boolean[propertySpan];
    propertyLaziness = new boolean[propertySpan];
    cascadeStyles = new CascadeStyle[propertySpan];
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // generated value strategies
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    this.inMemoryValueGenerationStrategies = new InMemoryValueGenerationStrategy[propertySpan];
    this.inDatabaseValueGenerationStrategies = new InDatabaseValueGenerationStrategy[propertySpan];

    boolean foundPreInsertGeneratedValues = false;
    boolean foundPreUpdateGeneratedValues = false;
    boolean foundPostInsertGeneratedValues = false;
    boolean foundPostUpdateGeneratedValues = false;
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Iterator iter = persistentClass.getPropertyClosureIterator();
    int i = 0;
    int tempVersionProperty = NO_VERSION_INDX;
    boolean foundCascade = false;
    boolean foundCollection = false;
    boolean foundMutable = false;
    boolean foundNonIdentifierPropertyNamedId = false;
    boolean foundInsertGeneratedValue = false;
    boolean foundUpdateGeneratedValue = false;
    boolean foundUpdateableNaturalIdProperty = false;

    while (iter.hasNext()) {
      Property prop = (Property) iter.next();

      if (prop == persistentClass.getVersion()) {
        tempVersionProperty = i;
        properties[i] =
            PropertyFactory.buildVersionProperty(
                persister, sessionFactory, i, prop, instrumentationMetadata.isInstrumented());
      } else {
        properties[i] =
            PropertyFactory.buildEntityBasedAttribute(
                persister, sessionFactory, i, prop, instrumentationMetadata.isInstrumented());
      }

      if (prop.isNaturalIdentifier()) {
        naturalIdNumbers.add(i);
        if (prop.isUpdateable()) {
          foundUpdateableNaturalIdProperty = true;
        }
      }

      if ("id".equals(prop.getName())) {
        foundNonIdentifierPropertyNamedId = true;
      }

      // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      boolean lazy = prop.isLazy() && instrumentationMetadata.isInstrumented();
      if (lazy) hasLazy = true;
      propertyLaziness[i] = lazy;

      propertyNames[i] = properties[i].getName();
      propertyTypes[i] = properties[i].getType();
      propertyNullability[i] = properties[i].isNullable();
      propertyUpdateability[i] = properties[i].isUpdateable();
      propertyInsertability[i] = properties[i].isInsertable();
      propertyVersionability[i] = properties[i].isVersionable();
      nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
      propertyCheckability[i] =
          propertyUpdateability[i]
              || (propertyTypes[i].isAssociationType()
                  && ((AssociationType) propertyTypes[i]).isAlwaysDirtyChecked());

      cascadeStyles[i] = properties[i].getCascadeStyle();
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      // generated value strategies
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      GenerationStrategyPair pair = buildGenerationStrategyPair(sessionFactory, prop);
      inMemoryValueGenerationStrategies[i] = pair.getInMemoryStrategy();
      inDatabaseValueGenerationStrategies[i] = pair.getInDatabaseStrategy();

      if (pair.getInMemoryStrategy() != null) {
        final GenerationTiming timing = pair.getInMemoryStrategy().getGenerationTiming();
        if (timing != GenerationTiming.NEVER) {
          final ValueGenerator generator = pair.getInMemoryStrategy().getValueGenerator();
          if (generator != null) {
            // we have some level of generation indicated
            if (timing == GenerationTiming.INSERT) {
              foundPreInsertGeneratedValues = true;
            } else if (timing == GenerationTiming.ALWAYS) {
              foundPreInsertGeneratedValues = true;
              foundPreUpdateGeneratedValues = true;
            }
          }
        }
      }
      if (pair.getInDatabaseStrategy() != null) {
        final GenerationTiming timing = pair.getInDatabaseStrategy().getGenerationTiming();
        if (timing == GenerationTiming.INSERT) {
          foundPostInsertGeneratedValues = true;
        } else if (timing == GenerationTiming.ALWAYS) {
          foundPostInsertGeneratedValues = true;
          foundPostUpdateGeneratedValues = true;
        }
      }
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      if (properties[i].isLazy()) {
        hasLazy = true;
      }

      if (properties[i].getCascadeStyle() != CascadeStyles.NONE) {
        foundCascade = true;
      }

      if (indicatesCollection(properties[i].getType())) {
        foundCollection = true;
      }

      if (propertyTypes[i].isMutable() && propertyCheckability[i]) {
        foundMutable = true;
      }

      mapPropertyToIndex(prop, i);
      i++;
    }

    if (naturalIdNumbers.size() == 0) {
      naturalIdPropertyNumbers = null;
      hasImmutableNaturalId = false;
      hasCacheableNaturalId = false;
    } else {
      naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
      hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
      hasCacheableNaturalId = persistentClass.getNaturalIdCacheRegionName() != null;
    }

    this.hasPreInsertGeneratedValues = foundPreInsertGeneratedValues;
    this.hasPreUpdateGeneratedValues = foundPreUpdateGeneratedValues;
    this.hasInsertGeneratedValues = foundPostInsertGeneratedValues;
    this.hasUpdateGeneratedValues = foundPostUpdateGeneratedValues;

    hasCascades = foundCascade;
    hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;
    versionPropertyIndex = tempVersionProperty;
    hasLazyProperties = hasLazy;
    if (hasLazyProperties) LOG.lazyPropertyFetchingAvailable(name);

    lazy =
        persistentClass.isLazy()
            && (
            // TODO: this disables laziness even in non-pojo entity modes:
            !persistentClass.hasPojoRepresentation()
                || !ReflectHelper.isFinalClass(persistentClass.getProxyInterface()));
    mutable = persistentClass.isMutable();
    if (persistentClass.isAbstract() == null) {
      // legacy behavior (with no abstract attribute specified)
      isAbstract =
          persistentClass.hasPojoRepresentation()
              && ReflectHelper.isAbstractClass(persistentClass.getMappedClass());
    } else {
      isAbstract = persistentClass.isAbstract().booleanValue();
      if (!isAbstract
          && persistentClass.hasPojoRepresentation()
          && ReflectHelper.isAbstractClass(persistentClass.getMappedClass())) {
        LOG.entityMappedAsNonAbstract(name);
      }
    }
    selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
    dynamicUpdate = persistentClass.useDynamicUpdate();
    dynamicInsert = persistentClass.useDynamicInsert();

    polymorphic = persistentClass.isPolymorphic();
    explicitPolymorphism = persistentClass.isExplicitPolymorphism();
    inherited = persistentClass.isInherited();
    superclass = inherited ? persistentClass.getSuperclass().getEntityName() : null;
    hasSubclasses = persistentClass.hasSubclasses();

    optimisticLockStyle = persistentClass.getOptimisticLockStyle();
    final boolean isAllOrDirty =
        optimisticLockStyle == OptimisticLockStyle.ALL
            || optimisticLockStyle == OptimisticLockStyle.DIRTY;
    if (isAllOrDirty && !dynamicUpdate) {
      throw new MappingException(
          "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name);
    }
    if (versionPropertyIndex != NO_VERSION_INDX && isAllOrDirty) {
      throw new MappingException(
          "version and optimistic-lock=all|dirty are not a valid combination : " + name);
    }

    hasCollections = foundCollection;
    hasMutableProperties = foundMutable;

    iter = persistentClass.getSubclassIterator();
    while (iter.hasNext()) {
      subclassEntityNames.add(((PersistentClass) iter.next()).getEntityName());
    }
    subclassEntityNames.add(name);

    if (persistentClass.hasPojoRepresentation()) {
      entityNameByInheritenceClassMap.put(
          persistentClass.getMappedClass(), persistentClass.getEntityName());
      iter = persistentClass.getSubclassIterator();
      while (iter.hasNext()) {
        final PersistentClass pc = (PersistentClass) iter.next();
        entityNameByInheritenceClassMap.put(pc.getMappedClass(), pc.getEntityName());
      }
    }

    entityMode = persistentClass.hasPojoRepresentation() ? EntityMode.POJO : EntityMode.MAP;
    final EntityTuplizerFactory entityTuplizerFactory =
        sessionFactory.getSettings().getEntityTuplizerFactory();
    final String tuplizerClassName = persistentClass.getTuplizerImplClassName(entityMode);
    if (tuplizerClassName == null) {
      entityTuplizer =
          entityTuplizerFactory.constructDefaultTuplizer(entityMode, this, persistentClass);
    } else {
      entityTuplizer =
          entityTuplizerFactory.constructTuplizer(tuplizerClassName, this, persistentClass);
    }
  }
Ejemplo n.º 12
0
  @SuppressWarnings({CompilerWarnings.UNCHECKED})
  private void buildEntityMetadatas() throws Exception {
    SessionFactoryImpl sessionFactory =
        ((SessionFactoryImpl) this.entityManagerFactory.getSessionFactory());
    Class<?> entityBindingMappedClass;
    Class<? extends SdcctEntity> entityMappedClass;
    String entityName, entityPropName, entityPropFieldName;
    EntityMetadata entityMetadata;
    Map<String, PropertyMetadata> entityPropMetadatas;
    IndexedTypeDescriptor indexedEntityDesc;
    Method entityPropGetterMethod;
    boolean entityIndexed, entityPropIndexed;
    PropertyDescriptor indexedEntityPropDesc;
    PropertyMetadata entityPropMetadata;
    BidiMap<Integer, String> entityPropOrder;
    String[] entityPropOrderNames;

    for (PersistentClass entityBinding : metadata.getEntityBindings()) {
      if (((entityBindingMappedClass = entityBinding.getMappedClass()) == null)
          || !SdcctEntity.class.isAssignableFrom(entityBindingMappedClass)) {
        continue;
      }

      entityPropMetadatas =
          (entityMetadata =
                  new EntityMetadataImpl(
                      (entityName = entityBinding.getEntityName()),
                      (entityIndexed =
                          (indexedEntityDesc =
                                  searchIntegrator.getIndexedTypeDescriptor(
                                      (entityMappedClass =
                                          ((Class<? extends SdcctEntity>)
                                              entityBindingMappedClass))))
                              .isIndexed()),
                      entityMappedClass,
                      entityBinding.getTable().getName()))
              .getProperties();

      this.entityMetadatas.put(
          ((Class<? extends SdcctEntity>) entityMappedClass.getInterfaces()[0]), entityMetadata);

      for (Property entityProp :
          IteratorUtils.asIterable(
              IteratorUtils.chainedIterator(
                  ((Iterator<Property>) entityBinding.getRootClass().getPropertyIterator()),
                  ((Iterator<Property>) entityBinding.getPropertyIterator())))) {
        entityPropName = entityProp.getName();
        entityPropGetterMethod = entityProp.getGetter(entityMappedClass).getMethod();

        if (entityProp.getColumnSpan() == 0) {
          continue;
        }

        entityPropIndexed =
            (entityIndexed
                && entityPropGetterMethod.isAnnotationPresent(Fields.class)
                && ((indexedEntityPropDesc = indexedEntityDesc.getProperty(entityPropName)) != null)
                && !indexedEntityPropDesc.isId());

        entityPropMetadatas.put(
            entityPropName,
            (entityPropMetadata =
                new PropertyMetadataImpl(
                    entityPropName,
                    entityPropIndexed,
                    ((Column) entityProp.getColumnIterator().next()).getName(),
                    entityProp.getType())));

        if (entityPropIndexed) {
          for (Field entityPropFieldAnno :
              entityPropGetterMethod.getAnnotation(Fields.class).value()) {
            if (entityPropFieldAnno.analyze() == Analyze.NO) {
              continue;
            }

            entityPropFieldName = entityPropFieldAnno.name();

            switch (entityPropFieldAnno.analyzer().definition()) {
              case DbAnalyzerNames.EDGE_NGRAM:
                entityPropMetadata.setEdgeNgramFieldName(entityPropFieldName);
                break;

              case DbAnalyzerNames.LOWERCASE:
                entityPropMetadata.setLowercaseFieldName(entityPropFieldName);
                break;

              case DbAnalyzerNames.NGRAM:
                entityPropMetadata.setNgramFieldName(entityPropFieldName);
                break;

              case DbAnalyzerNames.PHONETIC:
                entityPropMetadata.setPhoneticFieldName(entityPropFieldName);
                break;
            }
          }
        }
      }

      entityMetadata.setIdProperty(
          entityPropMetadatas.get(entityBinding.getIdentifierProperty().getName()));

      entityPropOrder = entityMetadata.getPropertyOrder();
      entityPropOrderNames = sessionFactory.getEntityPersister(entityName).getPropertyNames();

      for (int a = 0; a < entityPropOrderNames.length; a++) {
        entityPropOrder.put(a, entityPropOrderNames[a]);
      }
    }

    LOGGER.debug(
        String.format(
            "Processed metadata for %d entities: [%s]",
            this.entityMetadatas.size(),
            this.entityMetadatas
                .values()
                .stream()
                .map(NamedBean::getName)
                .collect(Collectors.joining(", "))));
  }
  public RevisionInfoConfigurationResult configure(
      Configuration cfg, ReflectionManager reflectionManager) {
    Iterator<PersistentClass> classes = (Iterator<PersistentClass>) cfg.getClassMappings();
    boolean revisionEntityFound = false;
    RevisionInfoGenerator revisionInfoGenerator = null;

    Class<?> revisionInfoClass = null;

    while (classes.hasNext()) {
      PersistentClass pc = classes.next();
      XClass clazz;
      try {
        clazz = reflectionManager.classForName(pc.getClassName(), this.getClass());
      } catch (ClassNotFoundException e) {
        throw new MappingException(e);
      }

      RevisionEntity revisionEntity = clazz.getAnnotation(RevisionEntity.class);
      if (revisionEntity != null) {
        if (revisionEntityFound) {
          throw new MappingException("Only one entity may be annotated with @RevisionEntity!");
        }

        // Checking if custom revision entity isn't audited
        if (clazz.getAnnotation(Audited.class) != null) {
          throw new MappingException("An entity annotated with @RevisionEntity cannot be audited!");
        }

        revisionEntityFound = true;

        MutableBoolean revisionNumberFound = new MutableBoolean();
        MutableBoolean revisionTimestampFound = new MutableBoolean();
        MutableBoolean modifiedEntityNamesFound = new MutableBoolean();

        searchForRevisionInfoCfg(
            clazz,
            reflectionManager,
            revisionNumberFound,
            revisionTimestampFound,
            modifiedEntityNamesFound);

        if (!revisionNumberFound.isSet()) {
          throw new MappingException(
              "An entity annotated with @RevisionEntity must have a field annotated "
                  + "with @RevisionNumber!");
        }

        if (!revisionTimestampFound.isSet()) {
          throw new MappingException(
              "An entity annotated with @RevisionEntity must have a field annotated "
                  + "with @RevisionTimestamp!");
        }

        revisionInfoEntityName = pc.getEntityName();
        revisionInfoClass = pc.getMappedClass();
        Class<? extends RevisionListener> revisionListenerClass =
            getRevisionListenerClass(revisionEntity.value());
        revisionInfoTimestampType = pc.getProperty(revisionInfoTimestampData.getName()).getType();
        if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()
            || DefaultTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(
                revisionInfoClass)
            || modifiedEntityNamesFound.isSet()) {
          // If tracking modified entities parameter is enabled, custom revision info entity is a
          // subtype
          // of DefaultTrackingModifiedEntitiesRevisionEntity class, or @ModifiedEntityNames
          // annotation is used.
          revisionInfoGenerator =
              new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(
                  revisionInfoEntityName,
                  revisionInfoClass,
                  revisionListenerClass,
                  revisionInfoTimestampData,
                  isTimestampAsDate(),
                  modifiedEntityNamesData);
          globalCfg.setTrackEntitiesChangedInRevisionEnabled(true);
        } else {
          revisionInfoGenerator =
              new DefaultRevisionInfoGenerator(
                  revisionInfoEntityName,
                  revisionInfoClass,
                  revisionListenerClass,
                  revisionInfoTimestampData,
                  isTimestampAsDate());
        }
      }
    }

    // In case of a custom revision info generator, the mapping will be null.
    Document revisionInfoXmlMapping = null;

    Class<? extends RevisionListener> revisionListenerClass =
        getRevisionListenerClass(RevisionListener.class);

    if (revisionInfoGenerator == null) {
      if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) {
        revisionInfoClass = DefaultTrackingModifiedEntitiesRevisionEntity.class;
        revisionInfoEntityName = DefaultTrackingModifiedEntitiesRevisionEntity.class.getName();
        revisionInfoGenerator =
            new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(
                revisionInfoEntityName,
                revisionInfoClass,
                revisionListenerClass,
                revisionInfoTimestampData,
                isTimestampAsDate(),
                modifiedEntityNamesData);
      } else {
        revisionInfoClass = DefaultRevisionEntity.class;
        revisionInfoGenerator =
            new DefaultRevisionInfoGenerator(
                revisionInfoEntityName,
                revisionInfoClass,
                revisionListenerClass,
                revisionInfoTimestampData,
                isTimestampAsDate());
      }
      revisionInfoXmlMapping = generateDefaultRevisionInfoXmlMapping();
    }

    return new RevisionInfoConfigurationResult(
        revisionInfoGenerator,
        revisionInfoXmlMapping,
        new RevisionInfoQueryCreator(
            revisionInfoEntityName,
            revisionInfoIdData.getName(),
            revisionInfoTimestampData.getName(),
            isTimestampAsDate()),
        generateRevisionInfoRelationMapping(),
        new RevisionInfoNumberReader(revisionInfoClass, revisionInfoIdData),
        globalCfg.isTrackEntitiesChangedInRevisionEnabled()
            ? new ModifiedEntityNamesReader(revisionInfoClass, modifiedEntityNamesData)
            : null,
        revisionInfoEntityName,
        revisionInfoClass,
        revisionInfoTimestampData);
  }
  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);
  }
Ejemplo n.º 15
0
  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;
  }
Ejemplo n.º 16
0
  // TODO refactor this code, there is a lot of duplication in this method
  public void doSecondPass(Map persistentClasses) throws MappingException {
    org.hibernate.mapping.OneToOne value =
        new org.hibernate.mapping.OneToOne(
            mappings, propertyHolder.getTable(), propertyHolder.getPersistentClass());
    final String propertyName = inferredData.getPropertyName();
    value.setPropertyName(propertyName);
    String referencedEntityName =
        ToOneBinder.getReferenceEntityName(inferredData, targetEntity, mappings);
    value.setReferencedEntityName(referencedEntityName);
    AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty());
    // value.setFetchMode( fetchMode );
    value.setCascadeDeleteEnabled(cascadeOnDelete);
    // value.setLazy( fetchMode != FetchMode.JOIN );

    if (!optional) value.setConstrained(true);
    value.setForeignKeyType(
        value.isConstrained()
            ? ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT
            : ForeignKeyDirection.FOREIGN_KEY_TO_PARENT);
    PropertyBinder binder = new PropertyBinder();
    binder.setName(propertyName);
    binder.setValue(value);
    binder.setCascade(cascadeStrategy);
    binder.setAccessType(inferredData.getDefaultAccess());
    Property prop = binder.makeProperty();
    if (BinderHelper.isEmptyAnnotationValue(mappedBy)) {
      /*
       * we need to check if the columns are in the right order
       * if not, then we need to create a many to one and formula
       * but actually, since entities linked by a one to one need
       * to share the same composite id class, this cannot happen in hibernate
       */
      boolean rightOrder = true;

      if (rightOrder) {
        String path = StringHelper.qualify(propertyHolder.getPath(), propertyName);
        (new ToOneFkSecondPass(
                value,
                joinColumns,
                !optional, // cannot have nullabe and unique on certain DBs
                propertyHolder.getEntityOwnerClassName(),
                path,
                mappings))
            .doSecondPass(persistentClasses);
        // no column associated since its a one to one
        propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
      } else {
        // this is a many to one with Formula

      }
    } else {
      PersistentClass otherSide =
          (PersistentClass) persistentClasses.get(value.getReferencedEntityName());
      Property otherSideProperty;
      try {
        if (otherSide == null) {
          throw new MappingException("Unable to find entity: " + value.getReferencedEntityName());
        }
        otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy);
      } catch (MappingException e) {
        throw new AnnotationException(
            "Unknown mappedBy in: "
                + StringHelper.qualify(ownerEntity, ownerProperty)
                + ", referenced property unknown: "
                + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
      }
      if (otherSideProperty == null) {
        throw new AnnotationException(
            "Unknown mappedBy in: "
                + StringHelper.qualify(ownerEntity, ownerProperty)
                + ", referenced property unknown: "
                + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
      }
      if (otherSideProperty.getValue() instanceof OneToOne) {
        propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
      } else if (otherSideProperty.getValue() instanceof ManyToOne) {
        Iterator it = otherSide.getJoinIterator();
        Join otherSideJoin = null;
        while (it.hasNext()) {
          Join otherSideJoinValue = (Join) it.next();
          if (otherSideJoinValue.containsProperty(otherSideProperty)) {
            otherSideJoin = otherSideJoinValue;
            break;
          }
        }
        if (otherSideJoin != null) {
          // @OneToOne @JoinTable
          Join mappedByJoin =
              buildJoinFromMappedBySide(
                  (PersistentClass) persistentClasses.get(ownerEntity),
                  otherSideProperty,
                  otherSideJoin);
          ManyToOne manyToOne = new ManyToOne(mappings, mappedByJoin.getTable());
          // FIXME use ignore not found here
          manyToOne.setIgnoreNotFound(ignoreNotFound);
          manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled());
          manyToOne.setEmbedded(value.isEmbedded());
          manyToOne.setFetchMode(value.getFetchMode());
          manyToOne.setLazy(value.isLazy());
          manyToOne.setReferencedEntityName(value.getReferencedEntityName());
          manyToOne.setUnwrapProxy(value.isUnwrapProxy());
          prop.setValue(manyToOne);
          Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
          while (otherSideJoinKeyColumns.hasNext()) {
            Column column = (Column) otherSideJoinKeyColumns.next();
            Column copy = new Column();
            copy.setLength(column.getLength());
            copy.setScale(column.getScale());
            copy.setValue(manyToOne);
            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());
            manyToOne.addColumn(copy);
          }
          mappedByJoin.addProperty(prop);
        } else {
          propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
        }

        value.setReferencedPropertyName(mappedBy);

        String propertyRef = value.getReferencedPropertyName();
        if (propertyRef != null) {
          mappings.addUniquePropertyReference(value.getReferencedEntityName(), propertyRef);
        }
      } else {
        throw new AnnotationException(
            "Referenced property not a (One|Many)ToOne: "
                + StringHelper.qualify(otherSide.getEntityName(), mappedBy)
                + " in mappedBy of "
                + StringHelper.qualify(ownerEntity, ownerProperty));
      }
    }
    ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class);
    String fkName = fk != null ? fk.name() : "";
    if (!BinderHelper.isEmptyAnnotationValue(fkName)) value.setForeignKeyName(fkName);
  }