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); } }
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); } }
@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; }
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); } } } }
/** * @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; }