public void setParameterValues(Properties parameters) {
    String enumClassName = parameters.getProperty("enumClass");
    try {
      enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
    } catch (ClassNotFoundException cfne) {
      throw new HibernateException("Enum class not found", cfne);
    }

    String identifierMethodName =
        parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);

    try {
      identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
      identifierType = identifierMethod.getReturnType();
    } catch (Exception e) {
      throw new HibernateException("Failed to obtain identifier method", e);
    }

    type = (NullableType) TypeFactory.basic(identifierType.getName());

    if (type == null)
      throw new HibernateException("Unsupported identifier type " + identifierType.getName());

    sqlTypes = new int[] {type.sqlType()};

    String valueOfMethodName =
        parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);

    try {
      valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] {identifierType});
    } catch (Exception e) {
      throw new HibernateException("Failed to obtain valueOf method", e);
    }
  }
Example #2
0
 public Type getType() throws MappingException {
   return TypeFactory.manyToOne(
       getReferencedEntityName(),
       getReferencedPropertyName(),
       isLazy(),
       isUnwrapProxy(),
       isEmbedded(),
       isIgnoreNotFound());
 }
 public void setText(String s) {
   // for some reason the antlr.CommonAST initialization routines force
   // this method to get called twice.  The first time with an empty string
   if (StringHelper.isNotEmpty(s)) {
     constantExpression = s;
     constantValue = ReflectHelper.getConstantValue(s);
     heuristicType = TypeFactory.heuristicType(constantValue.getClass().getName());
     super.setText(s);
   }
 }
Example #4
0
  @SuppressWarnings({"unchecked", "RedundantCast"})
  private void extractParameterInfo(Map<String, Class> namedParameterTypeRedefinition) {
    if (!AbstractQueryImpl.class.isInstance(query)) {
      throw new IllegalStateException("Unknown query type for parameter extraction");
    }

    HashSet<Parameter<?>> parameters = new HashSet<Parameter<?>>();
    AbstractQueryImpl queryImpl = AbstractQueryImpl.class.cast(query);

    // extract named params
    for (String name : (Set<String>) queryImpl.getParameterMetadata().getNamedParameterNames()) {
      final NamedParameterDescriptor descriptor =
          queryImpl.getParameterMetadata().getNamedParameterDescriptor(name);
      Class javaType = namedParameterTypeRedefinition.get(name);
      if (javaType != null && mightNeedRedefinition(javaType)) {
        descriptor.resetExpectedType(TypeFactory.heuristicType(javaType.getName()));
      } else if (descriptor.getExpectedType() != null) {
        javaType = descriptor.getExpectedType().getReturnedClass();
      }
      final ParameterImpl parameter = new ParameterImpl(name, javaType);
      parameters.add(parameter);
      if (descriptor.isJpaStyle()) {
        if (jpaPositionalIndices == null) {
          jpaPositionalIndices = new HashSet<Integer>();
        }
        jpaPositionalIndices.add(Integer.valueOf(name));
      }
    }

    // extract positional parameters
    for (int i = 0, max = queryImpl.getParameterMetadata().getOrdinalParameterCount();
        i < max;
        i++) {
      final OrdinalParameterDescriptor descriptor =
          queryImpl.getParameterMetadata().getOrdinalParameterDescriptor(i + 1);
      ParameterImpl parameter =
          new ParameterImpl(
              i + 1,
              descriptor.getExpectedType() == null
                  ? null
                  : descriptor.getExpectedType().getReturnedClass());
      parameters.add(parameter);
      Integer position = descriptor.getOrdinalPosition();
      if (jpaPositionalIndices != null && jpaPositionalIndices.contains(position)) {
        log.warn(
            "Parameter position ["
                + position
                + "] occurred as both JPA and Hibernate positional parameter");
      }
    }

    this.parameters = java.util.Collections.unmodifiableSet(parameters);
  }
  private Object assembleCacheEntry(
      final CacheEntry entry,
      final Serializable id,
      final EntityPersister persister,
      final LoadEvent event)
      throws HibernateException {

    final Object optionalObject = event.getInstanceToLoad();
    final EventSource session = event.getSession();
    final SessionFactoryImplementor factory = session.getFactory();

    if (log.isTraceEnabled()) {
      log.trace(
          "assembling entity from second-level cache: "
              + MessageHelper.infoString(persister, id, factory));
    }

    EntityPersister subclassPersister = factory.getEntityPersister(entry.getSubclass());
    Object result =
        optionalObject == null ? session.instantiate(subclassPersister, id) : optionalObject;

    // make it circular-reference safe
    TwoPhaseLoad.addUninitializedCachedEntity(
        new EntityKey(id, subclassPersister, session.getEntityMode()),
        result,
        subclassPersister,
        LockMode.NONE,
        entry.areLazyPropertiesUnfetched(),
        entry.getVersion(),
        session);

    Type[] types = subclassPersister.getPropertyTypes();
    Object[] values =
        entry.assemble(
            result,
            id,
            subclassPersister,
            session.getInterceptor(),
            session); // intializes result by side-effect
    TypeFactory.deepCopy(
        values, types, subclassPersister.getPropertyUpdateability(), values, session);

    Object version = Versioning.getVersion(values, subclassPersister);
    if (log.isTraceEnabled()) log.trace("Cached Version: " + version);

    final PersistenceContext persistenceContext = session.getPersistenceContext();
    persistenceContext.addEntry(
        result,
        Status.MANAGED,
        values,
        null,
        id,
        version,
        LockMode.NONE,
        true,
        subclassPersister,
        false,
        entry.areLazyPropertiesUnfetched());
    subclassPersister.afterInitialize(result, entry.areLazyPropertiesUnfetched(), session);
    persistenceContext.initializeNonLazyCollections();
    // upgrade the lock if necessary:
    // lock(result, lockMode);

    // PostLoad is needed for EJB3
    // TODO: reuse the PostLoadEvent...
    PostLoadEvent postLoadEvent =
        new PostLoadEvent(session).setEntity(result).setId(id).setPersister(persister);
    PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
    for (int i = 0; i < listeners.length; i++) {
      listeners[i].onPostLoad(postLoadEvent);
    }

    return result;
  }
Example #6
0
 public CollectionType getDefaultCollectionType() {
   return TypeFactory.bag(getRole(), getReferencedPropertyName(), isEmbedded());
 }
  /**
   * Perform the second step of 2-phase load. Fully initialize the entity instance.
   *
   * <p>After processing a JDBC result set, we "resolve" all the associations between the entities
   * which were instantiated and had their state "hydrated" into an array
   */
  public static void initializeEntity(
      final Object entity,
      final boolean readOnly,
      final SessionImplementor session,
      final PreLoadEvent preLoadEvent,
      final PostLoadEvent postLoadEvent)
      throws HibernateException {

    // TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

    final PersistenceContext persistenceContext = session.getPersistenceContext();
    EntityEntry entityEntry = persistenceContext.getEntry(entity);
    if (entityEntry == null) {
      throw new AssertionFailure("possible non-threadsafe access to the session");
    }
    EntityPersister persister = entityEntry.getPersister();
    Serializable id = entityEntry.getId();
    Object[] hydratedState = entityEntry.getLoadedState();

    if (log.isDebugEnabled())
      log.debug(
          "resolving associations for "
              + MessageHelper.infoString(persister, id, session.getFactory()));

    Type[] types = persister.getPropertyTypes();
    for (int i = 0; i < hydratedState.length; i++) {
      final Object value = hydratedState[i];
      if (value != LazyPropertyInitializer.UNFETCHED_PROPERTY
          && value != BackrefPropertyAccessor.UNKNOWN) {
        hydratedState[i] = types[i].resolve(value, session, entity);
      }
    }

    // Must occur after resolving identifiers!
    if (session.isEventSource()) {
      preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
      PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
      for (int i = 0; i < listeners.length; i++) {
        listeners[i].onPreLoad(preLoadEvent);
      }
    }

    persister.setPropertyValues(entity, hydratedState, session.getEntityMode());

    final SessionFactoryImplementor factory = session.getFactory();
    if (persister.hasCache() && session.getCacheMode().isPutEnabled()) {

      if (log.isDebugEnabled())
        log.debug(
            "adding entity to second-level cache: "
                + MessageHelper.infoString(persister, id, session.getFactory()));

      Object version = Versioning.getVersion(hydratedState, persister);
      CacheEntry entry =
          new CacheEntry(
              hydratedState,
              persister,
              entityEntry.isLoadedWithLazyPropertiesUnfetched(),
              version,
              session,
              entity);
      CacheKey cacheKey =
          new CacheKey(
              id,
              persister.getIdentifierType(),
              persister.getRootEntityName(),
              session.getEntityMode(),
              session.getFactory());
      boolean put =
          persister
              .getCache()
              .put(
                  cacheKey,
                  persister.getCacheEntryStructure().structure(entry),
                  session.getTimestamp(),
                  version,
                  persister.isVersioned() ? persister.getVersionType().getComparator() : null,
                  useMinimalPuts(
                      session,
                      entityEntry)); // we could use persister.hasLazyProperties() instead of true

      if (put && factory.getStatistics().isStatisticsEnabled()) {
        factory
            .getStatisticsImplementor()
            .secondLevelCachePut(persister.getCache().getRegionName());
      }
    }

    if (readOnly || !persister.isMutable()) {
      // no need to take a snapshot - this is a
      // performance optimization, but not really
      // important, except for entities with huge
      // mutable property values
      persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
    } else {
      // take a snapshot
      TypeFactory.deepCopy(
          hydratedState,
          persister.getPropertyTypes(),
          persister.getPropertyUpdateability(),
          hydratedState, // after setting values to object, entityMode
          session);
      persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
    }

    persister.afterInitialize(entity, entityEntry.isLoadedWithLazyPropertiesUnfetched(), session);

    if (session.isEventSource()) {
      postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
      PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
      for (int i = 0; i < listeners.length; i++) {
        listeners[i].onPostLoad(postLoadEvent);
      }
    }

    if (log.isDebugEnabled())
      log.debug(
          "done materializing entity "
              + MessageHelper.infoString(persister, id, session.getFactory()));

    if (factory.getStatistics().isStatisticsEnabled()) {
      factory.getStatisticsImplementor().loadEntity(persister.getEntityName());
    }
  }
  /** WARNING: side-effecty */
  private String renderScalarSelect() {

    boolean isSubselect = superQuery != null;

    StringBuffer buf = new StringBuffer(20);

    if (scalarTypes.size() == 0) {
      // ie. no select clause
      int size = returnedTypes.size();
      for (int k = 0; k < size; k++) {

        scalarTypes.add(TypeFactory.manyToOne(persisters[k].getEntityName(), shallowQuery));

        String[] idColumnNames = persisters[k].getIdentifierColumnNames();
        for (int i = 0; i < idColumnNames.length; i++) {
          buf.append(returnedTypes.get(k)).append('.').append(idColumnNames[i]);
          if (!isSubselect) buf.append(" as ").append(NameGenerator.scalarName(k, i));
          if (i != idColumnNames.length - 1 || k != size - 1) buf.append(", ");
        }
      }

    } else {
      // there _was_ a select clause
      Iterator iter = scalarSelectTokens.iterator();
      int c = 0;
      boolean nolast = false; // real hacky...
      int parenCount = 0; // used to count the nesting of parentheses
      while (iter.hasNext()) {
        Object next = iter.next();
        if (next instanceof String) {
          String token = (String) next;

          if ("(".equals(token)) {
            parenCount++;
          } else if (")".equals(token)) {
            parenCount--;
          }

          String lc = token.toLowerCase();
          if (lc.equals(", ")) {
            if (nolast) {
              nolast = false;
            } else {
              if (!isSubselect && parenCount == 0) {
                int x = c++;
                buf.append(" as ").append(NameGenerator.scalarName(x, 0));
              }
            }
          }
          buf.append(token);
          if (lc.equals("distinct") || lc.equals("all")) {
            buf.append(' ');
          }
        } else {
          nolast = true;
          String[] tokens = (String[]) next;
          for (int i = 0; i < tokens.length; i++) {
            buf.append(tokens[i]);
            if (!isSubselect) {
              buf.append(" as ").append(NameGenerator.scalarName(c, i));
            }
            if (i != tokens.length - 1) buf.append(", ");
          }
          c++;
        }
      }
      if (!isSubselect && !nolast) {
        int x = c++;
        buf.append(" as ").append(NameGenerator.scalarName(x, 0));
      }
    }

    return buf.toString();
  }
  private void renderSQL() throws QueryException, MappingException {

    final int rtsize;
    if (returnedTypes.size() == 0 && scalarTypes.size() == 0) {
      // ie no select clause in HQL
      returnedTypes = fromTypes;
      rtsize = returnedTypes.size();
    } else {
      rtsize = returnedTypes.size();
      Iterator iter = entitiesToFetch.iterator();
      while (iter.hasNext()) {
        returnedTypes.add(iter.next());
      }
    }
    int size = returnedTypes.size();
    persisters = new Queryable[size];
    names = new String[size];
    owners = new int[size];
    ownerAssociationTypes = new EntityType[size];
    suffixes = new String[size];
    includeInSelect = new boolean[size];
    for (int i = 0; i < size; i++) {
      String name = (String) returnedTypes.get(i);
      // if ( !isName(name) ) throw new QueryException("unknown type: " + name);
      persisters[i] = getEntityPersisterForName(name);
      // TODO: cannot use generateSuffixes() - it handles the initial suffix differently.
      suffixes[i] = (size == 1) ? "" : Integer.toString(i) + '_';
      names[i] = name;
      includeInSelect[i] = !entitiesToFetch.contains(name);
      if (includeInSelect[i]) selectLength++;
      if (name.equals(collectionOwnerName)) collectionOwnerColumn = i;
      String oneToOneOwner = (String) oneToOneOwnerNames.get(name);
      owners[i] = (oneToOneOwner == null) ? -1 : returnedTypes.indexOf(oneToOneOwner);
      ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get(name);
    }

    if (ArrayHelper.isAllNegative(owners)) owners = null;

    String scalarSelect = renderScalarSelect(); // Must be done here because of side-effect! yuck...

    int scalarSize = scalarTypes.size();
    hasScalars = scalarTypes.size() != rtsize;

    returnTypes = new Type[scalarSize];
    for (int i = 0; i < scalarSize; i++) {
      returnTypes[i] = (Type) scalarTypes.get(i);
    }

    QuerySelect sql = new QuerySelect(getFactory().getDialect());
    sql.setDistinct(distinct);

    if (!shallowQuery) {
      renderIdentifierSelect(sql);
      renderPropertiesSelect(sql);
    }

    if (collectionPersister != null) {
      sql.addSelectFragmentString(collectionPersister.selectFragment(fetchName, "__"));
    }

    if (hasScalars || shallowQuery) sql.addSelectFragmentString(scalarSelect);

    // TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to
    // other select strings
    mergeJoins(sql.getJoinFragment());

    sql.setWhereTokens(whereTokens.iterator());

    sql.setGroupByTokens(groupByTokens.iterator());
    sql.setHavingTokens(havingTokens.iterator());
    sql.setOrderByTokens(orderByTokens.iterator());

    if (collectionPersister != null && collectionPersister.hasOrdering()) {
      sql.addOrderBy(collectionPersister.getSQLOrderByString(fetchName));
    }

    scalarColumnNames = NameGenerator.generateColumnNames(returnTypes, getFactory());

    // initialize the Set of queried identifier spaces (ie. tables)
    Iterator iter = collections.values().iterator();
    while (iter.hasNext()) {
      CollectionPersister p = getCollectionPersister((String) iter.next());
      addQuerySpaces(p.getCollectionSpaces());
    }
    iter = typeMap.keySet().iterator();
    while (iter.hasNext()) {
      Queryable p = getEntityPersisterForName((String) iter.next());
      addQuerySpaces(p.getQuerySpaces());
    }

    sqlString = sql.toQueryString();

    if (holderClass != null)
      holderConstructor = ReflectHelper.getConstructor(holderClass, returnTypes);

    if (hasScalars) {
      actualReturnTypes = returnTypes;
    } else {
      actualReturnTypes = new Type[selectLength];
      int j = 0;
      for (int i = 0; i < persisters.length; i++) {
        if (includeInSelect[i]) {
          actualReturnTypes[j++] =
              TypeFactory.manyToOne(persisters[i].getEntityName(), shallowQuery);
        }
      }
    }
  }
Example #10
0
  /**
   * @param column
   * @param generatedIdentifier
   * @return
   */
  private String guessAndAlignType(
      Table table, Column column, Mapping mapping, boolean generatedIdentifier) {
    // TODO: this method mutates the column if the types does not match...not good.
    // maybe we should copy the column instead before calling this method.
    Integer sqlTypeCode = column.getSqlTypeCode();
    String location =
        "Table: "
            + Table.qualify(table.getCatalog(), table.getSchema(), table.getQuotedName())
            + " column: "
            + column.getQuotedName();
    if (sqlTypeCode == null) {
      throw new JDBCBinderException("sqltype is null for " + location);
    }

    String preferredHibernateType =
        revengStrategy.columnToHibernateTypeName(
            TableIdentifier.create(table),
            column.getName(),
            sqlTypeCode.intValue(),
            column.getLength(),
            column.getPrecision(),
            column.getScale(),
            column.isNullable(),
            generatedIdentifier);

    Type wantedType = TypeFactory.heuristicType(preferredHibernateType);

    if (wantedType != null) {
      int[] wantedSqlTypes = wantedType.sqlTypes(mapping);

      if (wantedSqlTypes.length > 1) {
        throw new JDBCBinderException(
            "The type "
                + preferredHibernateType
                + " found on "
                + location
                + " spans multiple columns. Only single column types allowed.");
      }

      int wantedSqlType = wantedSqlTypes[0];
      if (wantedSqlType != sqlTypeCode.intValue()) {
        log.debug(
            "Sql type mismatch for "
                + location
                + " between DB and wanted hibernate type. Sql type set to "
                + typeCodeName(sqlTypeCode.intValue())
                + " instead of "
                + typeCodeName(wantedSqlType));
        column.setSqlTypeCode(new Integer(wantedSqlType));
      }
    } else {
      log.debug(
          "No Hibernate type found for "
              + preferredHibernateType
              + ". Most likely cause is a missing UserType class.");
    }

    if (preferredHibernateType == null) {
      throw new JDBCBinderException(
          "Could not find javatype for " + typeCodeName(sqlTypeCode.intValue()));
    }

    return preferredHibernateType;
  }