![](/img/trans.png)
[英]@Scheduled @Transactional lazy init collection error - no proxy
[英]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.