簡體   English   中英

初始化延遲集合時出錯

[英]Error Initializing Lazy Collection

我正在嘗試編寫一些代碼來確定客戶是否具有某些功能。 我有這種方法:

@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

我正在使用休眠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();
            }
        }
    }
}

在查看Customer類時,我看不到如何映射features集,但是請注意,無論如何,默認的LAZY存類型為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));

這樣,您可以告訴方法要與實體一起獲取哪些集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM