2012-07-19 48 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表示法。