2012-07-19 83 views
0

我正在使用Play Framework 1.2.5和morphia-1.2.9a模塊。我最初在我的模型上使用@Reference註釋,但由於(lazy = true)不能在@ Reference上工作,我需要使用ObjectIds進行切換。在試圖減少返工和裁員,我創建了以下MorphiaList:播放Morphia,無法抓取(通用)嵌入式對象的列表內容

package models.morphia; 

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.Iterator; 
import java.util.List; 

import models.Team; 

import org.bson.types.ObjectId; 

import com.google.code.morphia.annotations.Embedded; 
import com.google.code.morphia.annotations.Transient; 

import play.modules.morphia.Model; 
@Embedded 
public class MorphiaList<T extends MorphiaModel> implements Iterable<T>{ 
    @Embedded("ids") private List<ObjectId> modelIds; 
    @Transient List<T> models; 
    public void sort() 
    { 
     this.getAll(); 
     Collections.sort(models); 
     this.modelIds.clear(); 
     for(T t:this.models){ 
      this.modelIds.add((ObjectId)t.getId()); 
     } 
    } 
    public MorphiaList() 
    { 
     this.models = new ArrayList<T>(); 
     this.modelIds = new ArrayList<ObjectId>(); 
    } 
    public int size() 
    { 
     System.out.println(modelIds.size()); 
     return modelIds.size(); 
    } 
    public boolean add(T model) 
    { 
     return (this.models.add(model) && this.modelIds.add((ObjectId) model.getId())); 
    } 
    public boolean remove(T model) 
    { 
     return (this.models.remove(model)&&this.modelIds.remove((ObjectId) model.getId())); 
    } 
    public boolean addAll(Collection<? extends T> models) 
    { 
     for(T model: models) 
     { 
      this.models.add(model); 
      this.modelIds.add((ObjectId) model.getId()); 
     } 
     return false; 
    } 
    public List<T> getAll() 
    { 
     for(ObjectId oi: this.modelIds) 
     { 
      boolean found=false; 
      for(T model: models) 
      { 
       if(oi==model.getId()) 
       { 
        found=true; 
        break; 
       } 
      } 
      if(!found) 
       models.add(T.<T>findById(oi)); 
     } 
     return models; 
    } 
    public T get(int index) 
    { 
     ObjectId id = modelIds.get(index); 
     for(T model: models) 
     { 
      if(id == model.getId()) 
       return model; 
     } 
     return T.<T>findById(id); 
    } 
    @Override 
    public Iterator<T> iterator() { 
     return this.getModelIterator(); 
    } 
    public Iterator<T> getModelIterator() { 
     for(ObjectId oi: modelIds) 
     { 
      boolean found=false; 
      for(T model: models) 
      { 
       if(oi==model.getId()) 
       { 
        found=true; 
        break; 
       } 
      } 
      if(!found) 
       models.add(T.<T>findById(oi)); 
     } 
     return models.iterator(); 
    } 
    public boolean isEmpty() { 
     return this.modelIds.isEmpty(); 
    } 
    public boolean contains(T t) { 
     return this.modelIds.contains(t.getId()); 
    } 
} 

MorphiaModel很簡單,我只是需要它來實現可比,所以我可以我的列表進行排序:然後我用

package models.morphia; 
import play.modules.morphia.Model; 
public abstract class MorphiaModel<T extends MorphiaModel<T>> extends Model implements Comparable<T>{ 
} 

像這樣在我的課:

@Entity 
public class Organization extends Purchasable { 
@Embedded public MorphiaList<Season> seasons = new MorphiaList<Season>(); 

一旦我添加了一個賽季,蒙戈顯示預期:

{ 
"_id" : { "$oid" : "50097c147aa33c43fa8136ee"} , 
...other members... 
"seasons" : { "ids" : [ { "$oid" : "50097c147aa33c43fa8136ed"}]} , 
...other members... 
} 

當我去搶季節對象時,modelIds是空的!我不知道爲什麼它不能從BSON搶到季節,這顯然是存在的。任何幫助是極大的讚賞!

回答

0

我不能讓這出於多種原因的工作:

  1. 我不能讓一次數據持久化到MongoDB的加載回對象,該對象將永遠只是爲空。
  2. 問題#1後,我添加了一個私人列表,將填充我的MorphiaList查找來解決它。但是在將ids引入MorphiaList之後,我無法弄清楚如何查找特定的集合。特別是當你考慮我使用繼承,所以我有一些異構集合。

我的解決方案:對於引用的每個列表我改寫了這一點:

@Reference public List<Season> seasons; 

要這樣:

@Transient public List<Season> seasons; 
private List<ObjectId> _seasons = new ArrayList(); 
@Transient private List<Season> pSeasons; 
public List<Season> getSeasons() 
{ 
    if(pSeasons==null) 
    { 
     if(_seasons.size()!=0) 
      pSeasons = Season.find().<Season>field("_id").in(_seasons).asList(); 
     else 
      pSeasons = new ArrayList(); 
    } 
    return pSeasons; 
} 

我也不得不加入@PrePersist方法來檢查清單訪問:

@PrePersist void beforeSave() 
{ 
    if(pSeasons!=null) 
    { 
     _seasons.clear(); 
     for(Season s: pSeasons) 
     { 
      _seasons.add((ObjectId)s.getId()); 
     } 
    } 
} 

beforeSave()將不得不擴展您的代碼中的每個額外的引用列表。道德故事:

如果您使用Play的嗎啡模塊,請不要使用@Reference表示法。

相關問題