B
B
bromzh2015-05-15 10:44:08
Java
bromzh, 2015-05-15 10:44:08

How to parameterize @Qualifier in JavaEE CDI?

I have a service that provides access to a MongoDB client:

// MongoService.java
public interface MongoService {
    public MongoClient getClient();
}

And its implementation:
// MongoServiceImpl.java
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MongoServiceImpl implements MongoService {
    MongoClient client = null;

    @PostConstruct
    public void init() {
        client = new MongoClient();
    }

    @Override
    @Lock(LockType.READ)
    public MongoClient getClient() {
        return client;
    }
}

In order to reduce the amount of duplicated code, I want to make an annotation to be able to get the database object and collections through dependency injection:
//Mongo.java
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Mongo {
    @Nonbinding String database() default "default";
    @Nonbinding String collection() default "";
}

And the corresponding Producer:
// MongoProducer.java
@Stateless
public class MongoProducer {

    @EJB
    MongoService mongoService;

    @Produces
    @Mongo
    public MongoDatabase getDatabase(InjectionPoint injectionPoint) {
        Mongo annotation = injectionPoint.getAnnotated().getAnnotation(Mongo.class);
        return mongoService.getClient().getDatabase(annotation.database());
    }

    @Produces
    @Mongo
    public MongoCollection<Document> getCollection(InjectionPoint injectionPoint) {
        Mongo annotation = injectionPoint.getAnnotated().getAnnotation(Mongo.class);
        String collectionName = annotation.collection();
        if (Objects.equals(collectionName, "")) {
            return null;
        }
        return mongoService.getClient().getDatabase(annotation.database()).getCollection(collectionName);
    }
}

In driver version >3.0, collections are parameterized by document type. The default is org.bson.Document, but you need to be able to use your own type.
What needs to be added to the annotation @Mongoand class MongoProducerso that you can use your document type like this:
@Stateless
public class FooBean {
    @Inject
    @Mongo(collection = "foo", documentType = MyDocument.class)
    MongoCollection<MyDocument> collection;
    ...
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question