Cambridge Technology PartnersCommunity Documentation

Chapter 2. Core Concepts

2.1. DAOs
2.1.1. The EntityDao interface
2.1.2. The AbstractEntityDao class
2.2. Using Multiple EntityManagers

With the CDI Query Module, it is possible to make a DAO out of basically any abstract class or interface (using a concrete class will work too, but you won't be able to use most of the CDI Query features). All that is required is to mark the type as such with a simple annotation:

@Dao(Person.class)

public abstract class PersonDao {
    ...
}
@Dao(Person.class)
public interface PersonDao {
    ...
}    

The @Dao annotation tells CDI Query that this is a DAO for the Person entity. Any method defined on the DAO will be processed by the framework. The annotation does not require to set the entity class (we'll see later why) but if there are just plain classes or interfaces this is the only way to tell the framework what entity the DAO relates to. In order to simplify this, CDI Query provides several base types.

While most applications will run just fine with a single EntityManager, there might be setups where multiple data sources are used. Similar to the default case, CDI Query requires to have producers for each EntityManager to be used, and to distinguish them over a CDI qualifier.

@Qualifier

@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
public @interface CustomerData {
}
        
public class CustomerDataSourceProducer {
    ...
    @Produces @CustomerData
    public EntityManager create(){
        return emf.createEntityManager();
    }
}    

The @CustomerData is a CDI qualifier - all available EntityManager have to be exposed similar with a different qualifier. The link to the Query DAO happens then over a custom annotation on the DAO:

@Dao

@WithEntityManager(CustomerData.class)
public interface CustomerDao extends EntityDao<Customer, Long> {
    ...
}    

If a more granular qualifier support is required, the AbstractEntityDao class can be extended. The class provides a getEntityManager method, which can be overridden and annotated with the appropriate qualifiers:

@Qualifier

@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
public @interface CustomerData {
    CustomerType value();
}
        
public abstract class CustomerDao extends AbstractEntityDao<Customer, Long> {
    @Override @CustomerData(CRM)
    protected abstract EntityManager getEntityManager();
    
    ...
}