2014-09-30 69 views
1

我正在尝试使用Morphia作为我使用Java EE创建的Web服务的一部分。在Java EE中使用Morphia

我了解他们的DAO支持吗啡文档对此表示:一个扩展BasicDAO morhpia提供

In a web application environment, we would probably use a dependency injection framework (like Guice or Spring) to inject the dependencies into the DAO, and then inject the DAO into a controller, so the controller would never directly deal with the gritty details.

所以我有一个EJB标有@Stateless注释(这样我就可以注入,当我需要它)如下:

@Stateless 
public class PlayerDAO extends BasicDAO<Player, ObjectId>{ 

    @EJB 
    ConnectionFactory factory; 

    public PlayerDAO(){}; 

    public PlayerDAO(Morphia morphia, MongoClient mongo){ 
    super(mongo, morphia, "testdb"); 
    } 
} 

我的问题是,我需要提供取MorphiaMongoClient参数的构造,并调用superç onstructor,这意味着我还需要提供一个无参数构造函数来满足Java EE的要求。

当我加入这个构造的NetBeans显示了错误:

public PlayerDAO(){};
constructor BasicDAO.BasicDAO(Datastore) is not applicable
(actual and formal argument lists differ in length)
constructor BasicDAO.BasicDAO(MongoClient,Morphia,String) is not applicable
(actual and formal argument lists differ in length)
constructor BasicDAO.BasicDAO(Class,Datastore) is not applicable
(actual and formal argument lists differ in length)
constructor BasicDAO.BasicDAO(Class,MongoClient,Morphia,String) is not applicable
(actual and formal argument lists differ in length)

有没有办法来解决这个问题,或者我应该采取不同的方法,以便使用MongoDB的作为Java EE的一部分网络服务?

回答

0

这就是我们所做的,工作得很好。下面的实现只是CDI(部署到Tomcat),但也适用于@Stateless beans。我们让MongoMorphia@Produce d由工厂。 @QConfig带注释的名称由生产者生成,它从包含MongoDB数据库名称的类路径中读取.properties文件。

public interface EntityDao<T, K> { 
    T findById(K id); 
    K save(T object); 
    T update(T object); // returns an up-to-date version of the entity 
} 

public class BaseDaoMorphiaImpl<T extends BaseEntity, K> 
    implements EntityDao<T, K>, Serializable { 

    @Inject 
    private @QConfig String mongoDbName; 
    @Inject 
    private @QMongo Instance<Mongo> mongo; 
    @Inject 
    private @QMorphia Instance<Morphia> morphia; 

    // BasicDAO is not serializeable; always use wrapper getBasicDao() 
    private transient BasicDAO<T, K> basicDao; 
    private Class clazz; 

    public BaseDaoMorphiaImpl(Class clazz) { 
     this.clazz = clazz; 
    } 

    @PostConstruct 
    public void init() { 
     setupBasicDao(); 
    } 

    protected BasicDAO<T, K> getBasicDao() { 
     if (basicDao == null) 
      setupBasicDao(); 
     return basicDao; 
    } 

    private void setupBasicDao() { 
     basicDao = new BasicDAO<T, K>(clazz, mongo.get(), morphia.get(), mongoDbName); 
     basicDao.ensureIndexes(); 
    } 

    @Override 
    public T findById(K id) { 
     return getBasicDao().get(id); 
    } 

    @Override 
    public K save(T o) { 
     Key<T> key = getBasicDao().save(o); 
     return (K) key.getId(); 
    } 

    @Override 
    public T update(T o) { 
     return findById((K) o.getId()); 
    } 

    protected QueryResults<T> find(Query<T> query) { 
     return getBasicDao().find(query); 
    } 

    protected T findOne(Query<T> query) { 
     return getBasicDao().findOne(query); 
    }  

    protected Query<T> createQuery() { 
     return getBasicDao().getDatastore().createQuery(clazz); 
    } 
} 

例子:

public interface UserDao extends EntityDao<User, ObjectId> { 
    User findByEmail(String email); 
    User findByName(String name); 
    List<User> findAll(); 
} 

public class UserDaoMorphiaImpl extends BaseDaoMorphiaImpl<User, ObjectId> implements  UserDao { 

    @Inject 
    private Logger logger; 

    public UserDaoMorphiaImpl() { 
     super(User.class); 
    } 

    @Override 
    public User findByEmail(String email) { 
     Datastore ds = getBasicDao().getDatastore(); 
     User res = ds.find(User.class).filter("email = ", email).get(); 
     return res; 
    } 

    @Override 
    public User findByName(String name) { 
     Datastore ds = getBasicDao().getDatastore(); 
     User res = ds.find(User.class).filter("name = ", name).get(); 
     return res; 
    } 

    @Override 
    public List<User> findAll() { 
     return getBasicDao().find().asList(); 
    } 

    @Override 
    public ObjectId save(User user) {  
     return super.save(user); 
    }  
} 

对于更具体的查询,你可以使用这样的事情:

@Override 
public Iterator<Document> fetchNewest(int start, int count) { 
    return find(createQuery().order("-uploadDate").offset(start).limit(count)).iterator(); 
}