初始化延迟集合时出错

时间:2018-03-06 21:50:54

标签: java hibernate lazy-initialization

我试图编写一些代码来确定客户是否具有某些功能。我有这个方法:

@Transactional(readOnly = true)
public boolean customerHasFeature(String customerId, String feature) {
    Customer customer = customerDAO.findByCid(customerId);
    if(customer != null) {
        return customer.hasFeatureNamed(feature);
    }

    return false;
}

customerDAO方法在这里

@Transactional(readOnly = true)
public Customer findByCid(String cid) {
    List<Customer> customers = findByCriteriaImpl(Restrictions.eq("cid", cid));
    if(customers.size() > 0)
        return customers.get(0);
    return null;
}

在我检索客户后的customerHasFeature中,它没有加载这些功能,我收到了错误

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.socialware.model.Customer.features, no session or session was closed

调试findbyCid时,我可以看到在条件检索客户后加载的功能,但是当返回的客户到达customerHasFeature时,它有一个错误。

我尝试添加

Hibernate.initialize(customer.getFeatures());

在我用customerHasFeature方法调用customerDAO后,我得到了

org.hibernate.HibernateException: collection is not associated with any session

我正在使用hibernate 3,感谢任何帮助或指导。

编辑

这里是findByCriteriaImpl方法。

List<T> findByCriteriaImpl(Criterion... criterion) {
       Criteria crit = createCriteria(getPersistentClass());
       if (criterion != null) {
          for (Criterion c : criterion) {
               crit.add(c);
          }
       }
       long startTime = System.currentTimeMillis();
       List<T> toReturn = crit.list();
       reportQueryTimeForMonitoring(System.currentTimeMillis() - startTime, "findByCriteriaImpl", "for criteria " + crit);
       return toReturn;
}

客户类

public class Customer implements Serializable{
    private static final long serialVersionUID = -1L;

    @Field(index=Index.UN_TOKENIZED)
    private long customerId;

    private String cid;

    //@Field
    private String name;

    private Set<Feature> features;
    private boolean deleted = false;
    private String randomKey;

    public Customer() {
    }

    @Override
    public String toString() {
        return new StringBuilder()
            .append("Customer{")
            .append(customerId).append(", ")
            .append(cid).append(", ")
            .append(name).append(", ")
            .append(deleted)
            .append("}").toString();
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        Customer other = (Customer) obj;
        if(cid == null) {
            if(other.cid != null)
                return false;
        }
        else if(!cid.equals(other.cid))
            return false;
        if(customerId != other.customerId)
            return false;
        if(name == null) {
            if(other.name != null)
                return false;
        }
        else if(!name.equals(other.name))
            return false;
        return true;
    }

    public long getCustomerId() {
        return customerId;
    }

    public void setCustomerId(long customerId) {
        this.customerId = customerId;
    }

    public void addFeature(Feature feature) {
        if(null == getFeatures()) {
            features = new HashSet<Feature>();
        }
        features.add(feature);
    }

    public Set<Feature> getFeatures() {
        return features;
    }

    public void setFeatures(Set<Feature> features) {
        this.features = features;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    public String getRandomKey() {
        return randomKey;
    }

    public void setRandomKey(String randomKey) {
        this.randomKey = randomKey;
    }

    public boolean hasFeatureNamed(String name) {
        Set<Feature> features = getFeatures();

        if (features == null) {
            return false;
        }
        for (Feature feature : features) {
            if (feature != null && feature.getName().equals(name)) {
                return true;
            }
        }
        return false;
    }

    public void removeFeature(String name) {
        Set<Feature> features = getFeatures();

        if (features == null) {
            return;
        }
        for (Iterator<Feature> i = features.iterator(); i.hasNext();) {
            Feature feature = i.next();
            if (feature.getName().equals(name)) {
                i.remove();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

查看您的Customer课程,我无法看到您是如何映射features设置的,但请注意,无论您如何操作,默认提取类型为LAZY,这意味着您的在阅读期间不会初始化集合。

请尝试以下方法:

List<T> findByCriteriaImpl(List<String> fetches, Criterion... criterion) {
       Criteria crit = createCriteria(getPersistentClass());
       if (criterion != null) {
          for (Criterion c : criterion) {
               crit.add(c);
          }
          for (String s : fetches) {
               crit.setFetchMode(s, FetchMode.JOIN);
          }
       }
       long startTime = System.currentTimeMillis();
       List<T> toReturn = crit.list();
       reportQueryTimeForMonitoring(System.currentTimeMillis() - startTime, "findByCriteriaImpl", "for criteria " + crit);
       return toReturn;
}

并致电findByCriteriaImpl,如:

List<Customer> customers = findByCriteriaImpl(Collections.asList("features"), Restrictions.eq("cid", cid));

通过这种方式,您可以告诉您的方法要与您的实体一起获取哪些集合。