2013-10-01 6 views
1

Я пишу приложение Java EE 6, которое использует Morphia для сохранения объектов MongoDB. Я хотел бы иметь возможность @Inject моих классов DAO, где это необходимо, поэтому я создал класс Factory, который соответствующим образом создает DAO. Это выглядит примерно так:@ Вставить морфию DAO с CDI?

public class MyDAOFactory { 

    @Inject 
    private Datastore mongoDatastore = null; 

    /** 
    * Creates the DAO 
    */ 
    @Produces 
    @ApplicationScoped 
    public MyDAO createDAO() { 
     MyDAO dao = new MyDAO(
       this.mongoDatastore); 
     return dao; 
    } 
} 

код компилируется нормально, но когда я запускаю мое приложение на JBoss EAP 6.1 он жалуется, потому что MyDAO не имеет конструктора без аргументов. Я бы добавил один, но класс Morphia BasicDAO тоже не имеет такого, поэтому я не знаю, что так будет работать.

Есть ли способ для @Inject экземпляра DAO в моем EJB, сервлете и т. Д.? Или мне нужно каждый раз создавать экземпляры вручную?

+1

Я не знаю Морфию, но я * думаю * конструктор no-args необходим для CDI, чтобы иметь возможность проксировать компонент MyDAO. Я думаю, что это также может быть защищенный (или даже закрытый?) Конструктор, поэтому он не будет бесполезен для вашего публичного интерфейса. Если такой конструктор не может быть записан (например, потому что вы не можете предоставить соответствующие аргументы конструктору родительского класса ['BasicDAO']), то фабрика - это ваш единственный шанс, о котором я могу думать. –

+0

Да, проблема с прокси-сервером - вот почему CDI жалуется на отсутствие конструктора no-arg. Тем не менее, я думаю, что реализация такого класса Factory, как это, обойдется. Разве это не так? Есть ли способ лучше? – Shadowman

ответ

2

По какой-то причине CDI нуждается в конструкторе no-arg для MyDAO. Возможно, из-за того, как вы используете этот компонент (см. Спецификации ch.5.4 «Прокси-серверы клиента» по возможным причинам).

Вы не можете создать конструктор по умолчанию, так как базовый класс не один, а от того, что я вижу из code в super конструкторах сразу же использовать их аргументы. Поэтому передача null в super() из конструктора no-arg приведет к ошибкам.

Мое предложение состоит в том, чтобы создать интерфейс (возможно расширение org.mongodb.morphia.dao.DAO), например. MyDAOInterface, который имеет все публичные бизнес-методы MyDAO. Затем измените MyDAO реализовать этот интерфейс и изменить производитель вернуться MyDAOInterface:

public interface MyDAOInterface extends DAO {...} 

public class MyDAO implements MyDAOInterface { 
    // same implementation 
} 

public class MyDAOFactory { 
    @Inject 
    private Datastore mongoDatastore = null; 

    /** 
    * Creates the DAO 
    */ 
    @Produces 
    @ApplicationScoped 
    public MyDAOInterface createDAO() { 
     MyDAO dao = new MyDAO(this.mongoDatastore); 
     return dao; 
    } 
} 

Кстати, программирование интерфейсов имеет дополнительное преимущество делает ваш код более проверяемым, так что стоит несовершеннолетнего хлопот ,

Смежные вопросы