本文介绍了无法初始化代理-没有会话异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从事基于冬眠和春季的项目.我已经花了两天的时间,但是当我调用这段代码时,无法弄清楚为什么会出现惰性异常"错误:

I am working on the project which is based on hibernate and spring. I have spent two days but can't figure out why the "lazy exception" error is coming when i call this piece of code:

public MemberUser SendEmail(MemberUser user) throws MailSendingException {
    // Check if password will be sent by mail
    // Hibernate.initialize(user);
    user = fetchService.fetch(user, FETCH);
    // user = userDao.load(user.getId(), FETCH);
    final MemberGroup group = user.getMember().getMemberGroup();
    final boolean sendPasswordByEmail = group.getMemberSettings().isSendPasswordByEmail();

    String newPassword = null;
    if (sendPasswordByEmail) {
      // If send by mail, generate a new password
      newPassword = generatePassword(group);
    }

    // Update the user
    user.setPassword(hashHandler.hash(user.getSalt(), newPassword));
    user.setPasswordDate(null);
    userDao.update(user);

    if (sendPasswordByEmail) {
      // Send the password by mail
      mailHandler.sendResetPassword(user.getMember(), newPassword);
    }
    return user;
  }

此代码基本上是在从数据库中获取用户信息后,将电子邮件发送给用户以重置密码.异常来自"user = fetchService.fetch(user,FETCH)",而FETCH为:

This code is basically sending the email to the user for reset password after getting the user information from the db.Exception comes at "user= fetchService.fetch(user, FETCH)", while FETCH is :

private static final Relationship FETCH = RelationshipHelper.nested(User.Relationships.ELEMENT,
      Element.Relationships.GROUP);

这是fetch函数的代码,当调用fetch时,将执行该代码:

This is the code of the fetch function ,when the fetch is called this is executed:

@Override
public <E extends Entity> List<E> fetch(final Collection<E> entities, final Relationship... fetch) {
    if (entities == null) {
        return null;
    }
    final List<E> result = new ArrayList<E>(entities.size());
    for (E entity : entities) {
        entity = fetch(entity, fetch);
        result.add(entity);
    }
    return result;
}

这些是休眠类,但是我对它们没有把握.

These are hibernate classes but I don't have a grip on these .

public class HibernateHelper {
    */
    public static class QueryParameter {
        private final Object value;
        private final String operator;

        public QueryParameter(final Object value, final String operator) {
            this.value = value;
            this.operator = operator;
        }

        public String getOperator() {
            return operator;
        }

        public Object getValue() {
            return value;
        }
    }


    private static Map<Class<? extends Entity>, Set<String>> directPropertiesCache = new HashMap<Class<? extends Entity>, Set<String>>();


    public static void addInElementsParameter(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final Entity value) {
        if (value != null && value.isPersistent()) {
            final String parameterName = getParameterName(namedParameters, path);
            hql.append(" and :").append(parameterName).append(" in elements(").append(path).append(") ");
            namedParameters.put(parameterName, value);
        }
    }   public static void addInParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final Collection<?> values) {
        if (values != null && !values.isEmpty()) {
            final String parameterName = getParameterName(namedParameters, path);
            hql.append(" and ").append(path).append(" in (:").append(parameterName).append(") ");
            namedParameters.put(parameterName, values);
        }
    }

    /**
     * Adds an "in" operator parameter to the HQL query, if the given value is not empty, appending the values to the named parameters map
     */
    public static void addInParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final Object... values) {
        if (values != null && values.length > 0) {
            addInParameterToQuery(hql, namedParameters, path, Arrays.asList(values));
        }
    }

    /**
     * Adds a 'path like %value%' parameter to the HQL query if the given value is not empty, appending the value to the named parameters map
     */
    public static void addLikeParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final String value) {
        doAddLike(hql, namedParameters, path, value, false);
    }

    /**
     * Adds a equals parameter to the HQL query, if the given value is not empty, appending the value to the named parameters map
     */
    public static void addParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final Object value) {
        addParameterToQueryOperator(hql, namedParameters, path, "=", value);
    }

    /**
     * Adds a custom parameter to the HQL query, if the given parameter is not empty, appending the value to the named parameters map
     */
    public static void addParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final QueryParameter parameter) {
        if (parameter != null) {
            addParameterToQueryOperator(hql, namedParameters, path, parameter.getOperator(), parameter.getValue());
        }
    }

    /**
     * Adds a custom operator parameter to the HQL query, if the given value is not empty, appending the value to the named parameters map
     */
    public static void addParameterToQueryOperator(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final String operator, final Object value) {
        if (value != null && !"".equals(value)) {
            final String parameterName = getParameterName(namedParameters, path);
            hql.append(" and ").append(path).append(" ").append(operator).append(" :").append(parameterName).append(" ");
            namedParameters.put(parameterName, value);
        }
    }

    /**
     * Adds a period test to the HQL query, if the given period is not empty, appending the value to the named parameters map. See {@link Period}, as
     * it controls whether the begin and end dates are inclusive / exclusive.
     *
     */
    public static void addPeriodParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final Period period) {
        addParameterToQuery(hql, namedParameters, path, getBeginParameter(period));
        addParameterToQuery(hql, namedParameters, path, getEndParameter(period));
    }

    /**
     * Adds a 'path like value%' parameter to the HQL query if the given value is not empty, appending the value to the named parameters map
     */
    public static void addRightLikeParameterToQuery(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, final String value) {
        doAddLike(hql, namedParameters, path, value, true);
    }

    /**
     * Appends the join portion on the query to fetch the specified relationships, when appliable
     */
    public static void appendJoinFetch(final StringBuilder hql, final Class<? extends Entity> entityType, final String entityAlias, final Collection<Relationship> fetch) {
        if (fetch != null) {
            final Set<String> directRelationships = getDirectRelationshipProperties(entityType, fetch);

            for (final String directRelationship : directRelationships) {
                hql.append(" left join fetch ").append(entityAlias).append(".").append(directRelationship).append(" ");
            }
        }
    }

    /**
     * Appends the order by portion, with the given path lists (with an optional direction, ie: "e.date desc", "e.name", "x.name")
     */
    public static void appendOrder(final StringBuilder hql, final Collection<String> paths) {
        if (CollectionUtils.isNotEmpty(paths)) {
            hql.append(" order by " + StringUtils.join(paths.iterator(), ","));
        }
    }

    /**
     * Appends the order by portion, with the given path lists (with an optional direction, ie: "e.date desc", "e.name", "x.name")
     */
    public static void appendOrder(final StringBuilder hql, final String... paths) {
        if (paths != null && paths.length > 0) {
            appendOrder(hql, Arrays.asList(paths));
        }
    }

    /**
     * Returns the begin date of the given period, handling null
     */
    public static QueryParameter getBeginParameter(final Period period) {
        if (period == null) {
            return null;
        }
        Calendar begin = period.getBegin();
        if (begin == null) {
            return null;
        }
        // We must consider the time when explicitly set
        if (!period.isUseTime()) {
            // Truncate the begin date
            begin = DateHelper.truncate(begin);
        }
        String operator = period.isInclusiveBegin() ? ">=" : ">";
        return new QueryParameter(begin, operator);
    }

    /**
     * Returns the end date of the given period, handling null
     */
    public static QueryParameter getEndParameter(final Period period) {
        if (period == null) {
            return null;
        }
        Calendar end = period.getEnd();
        if (end == null) {
            return null;
        }
        // We must consider the time when explicitly set
        if (!period.isUseTime()) {
            // Truncate the end date and set the next day
            end = DateHelper.getDayEnd(end);
        }
        String operator = period.isInclusiveEnd() ? "<=" : "<";
        return new QueryParameter(end, operator);
    }

    /**
     * Returns a StringBuilder containing the begin of a single entity select HQL
     * @param entityType The entity type to search
     * @param entityAlias The entity alias on the query
     * @return The StringBuiler
     */
    public static StringBuilder getInitialQuery(final Class<? extends Entity> entityType, final String entityAlias) {
        return getInitialQuery(entityType, entityAlias, null);
    }

    /**
     * Returns a StringBuilder containing the begin of a single entity select HQL, with the especified fetch relationships, when appliable
     * @param entityType The entity type to search
     * @param entityAlias The entity alias on the query
     * @param fetch The relationships to fetch
     * @return The StringBuiler
     */
    public static StringBuilder getInitialQuery(final Class<? extends Entity> entityType, final String entityAlias, final Collection<Relationship> fetch) {
        final StringBuilder hql = new StringBuilder(" from ").append(entityType.getName()).append(" ").append(entityAlias).append(" ");
        appendJoinFetch(hql, entityType, entityAlias, fetch);
        hql.append(" where 1=1 ");
        return hql;
    }

    private static void doAddLike(final StringBuilder hql, final Map<String, Object> namedParameters, final String path, String value, final boolean rightOnly) {
        value = StringUtils.trimToNull(value);
        if (value == null) {
            return;
        }
        // Remove any manually entered '%'
        value = StringUtils.trimToNull(StringUtils.replace(value, "%", ""));
        if (value == null) {
            return;
        }
        // Assuming the default database collation is case insensitive, we don't need to perform case transformations
        if (rightOnly) {
            value += "%";
        } else {
            value = "%" + value + "%";
        }
        addParameterToQueryOperator(hql, namedParameters, path, "like", value);
    }

    /**
     * Returns a set of properties that will be fetched directly on the HQL
     */
    private static Set<String> getDirectRelationshipProperties(final Class<? extends Entity> entityType, final Collection<Relationship> fetch) {
        // Populate the direct properties cache for this entity if not yet exists
        Set<String> cachedDirectProperties = directPropertiesCache.get(entityType);
        if (cachedDirectProperties == null) {
            cachedDirectProperties = new HashSet<String>();
            final PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(entityType);
            // Scan for child -> parent relationships
            for (final PropertyDescriptor descriptor : propertyDescriptors) {
                if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null && Entity.class.isAssignableFrom(descriptor.getPropertyType())) {
                    // This is a child -> parent relationship. Add it to the cache
                    cachedDirectProperties.add(descriptor.getName());
                }
            }
            directPropertiesCache.put(entityType, cachedDirectProperties);
        }

        // Build the properties to add to HQL fetch from a given relationship set
        final Set<String> propertiesToAddToFetch = new HashSet<String>();
        for (final Relationship relationship : fetch) {
            final String name = PropertyHelper.firstProperty(relationship.getName());
            if (cachedDirectProperties.contains(name)) {
                propertiesToAddToFetch.add(name);
            }
        }
        return propertiesToAddToFetch;
    }

    /**
     * Generates a parameter name
     */
    private static String getParameterName(final Map<String, Object> namedParameters, final String propertyName) {
        int counter = 1;

        // Transform the property in a valid identifier
        final StringBuilder sb = new StringBuilder(propertyName.length());
        for (int i = 0, len = propertyName.length(); i < len; i++) {
            final char c = propertyName.charAt(i);
            if (Character.isJavaIdentifierPart(c)) {
                sb.append(c);
            } else {
                sb.append('_');
            }
        }

        final String field = sb.toString();
        String parameterName = field.concat("_1");
        while (namedParameters.containsKey(parameterName)) {
            parameterName = field.concat("_").concat(String.valueOf(++counter));
        }
        return parameterName;
    }

}

这是错误:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at nl.strohalm.cyclos.utils.hibernate.HibernateQueryHandler.initialize(HibernateQueryHandler.java:252)
    at nl.strohalm.cyclos.dao.FetchDAOImpl.doFetch(FetchDAOImpl.java:80)
    at nl.strohalm.cyclos.dao.FetchDAOImpl.fetch(FetchDAOImpl.java:37)
    at nl.strohalm.cyclos.services.fetch.FetchServiceImpl.fetch(FetchServiceImpl.java:45)
    at nl.strohalm.cyclos.services.access.AccessServiceImpl.SendEmail(AccessServiceImpl.java:1695)
    at nl.strohalm.cyclos.services.access.AccessServiceImpl.resetPasswordAndSendAfterExpire(AccessServiceImpl.java:1732)
    at com.omnia.payo.scheduling.task.UserLoginInfoSchedulingTask.doRun(UserLoginInfoSchedulingTask.java:43)
    at nl.strohalm.cyclos.scheduling.tasks.BaseScheduledTask.run(BaseScheduledTask.java:42)
    at nl.strohalm.cyclos.utils.tasks.TaskRunnerImpl$4.run(TaskRunnerImpl.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at nl.strohalm.cyclos.utils.access.LoggedUser.runAsSystem(LoggedUser.java:285)
    at nl.strohalm.cyclos.utils.tasks.TaskRunnerImpl.doRunScheduledTask(TaskRunnerImpl.java:190)
    at nl.strohalm.cyclos.utils.tasks.TaskRunnerImpl.doRunScheduledTask(TaskRunnerImpl.java:170)
    at nl.strohalm.cyclos.utils.tasks.TaskRunnerImpl$ScheduledTaskThreads.process(TaskRunnerImpl.java:64)
    at nl.strohalm.cyclos.utils.tasks.TaskRunnerImpl$ScheduledTaskThreads.process(TaskRunnerImpl.java:1)
    at nl.strohalm.cyclos.utils.ParallelTask$1.process(ParallelTask.java:43)
    at nl.strohalm.cyclos.utils.WorkerThreads$WorkerThread$1.call(WorkerThreads.java:53)
    at nl.strohalm.cyclos.utils.WorkerThreads$WorkerThread$1.call(WorkerThreads.java:1)
    at nl.strohalm.cyclos.utils.access.LoggedUser.runAsSystem(LoggedUser.java:285)
    at nl.strohalm.cyclos.utils.WorkerThreads$WorkerThread.run(WorkerThreads.java:49)

FetchDAOImpl中doFetch的代码为:

Code for doFetch in FetchDAOImpl is:

private <E extends Entity> E doFetch(final E inputEntity, final Relationship... fetch) {
        if (inputEntity == null || inputEntity.getId() == null) {
            throw new UnexpectedEntityException();
        }
        E entity;

        // Discover the entity real class and id
        final Class<? extends Entity> entityType = EntityHelper.getRealClass(inputEntity);
        final Long id = inputEntity.getId();

        // Load and initialize the entity
        try {
            entity = (E) getHibernateTemplate().load(entityType, id);
            entity = (E) hibernateQueryHandler.initialize(entity);
        } catch (final ObjectRetrievalFailureException e) {
            throw new EntityNotFoundException(entityType, id);
        } catch (final ObjectNotFoundException e) {
            throw new EntityNotFoundException(entityType, id);
        }

        // ... and fetch each relationship
        if (!ArrayUtils.isEmpty(fetch)) {
            for (final Relationship relationship : fetch) {
                if (relationship == null) {
                    continue;
                }
                try {
                    final String name = relationship.getName();
                    Object bean = entity;
                    String first = PropertyHelper.firstProperty(name);
                    String nested = PropertyHelper.nestedPath(name);
                    while (bean != null && first != null) {
                        final Object value = hibernateQueryHandler.initializeProperty(bean, first);
                        bean = value;
                        first = PropertyHelper.firstProperty(nested);
                        nested = PropertyHelper.nestedPath(nested);
                    }
                } catch (final PropertyException e) {
                    // Ok - nonexisting property. Probably fetching a relationship that only exists in one of the subclasses, and trying to use it no
                    // another one
                } catch (final Exception e) {
                    throw new PropertyException(entity, relationship.getName(), e);
                }
            }
        }
        return entity;
    }

请有人帮助我,我会非常感激.

please someone help me ,i'll be really thankful.

推荐答案

这应该是有帮助的:

什么是OpenSessionInViewFilter以及如何实现

从不同会话中进行休眠更新

或者这是给专家的

https://stackoverflow.com/a/32046337/3252285

这篇关于无法初始化代理-没有会话异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 20:06