Yes, I think we would be better off with a generic approach like that. Except that preCreate can't accept an EMF, as we have not created it yet :) The required contracts would be better placed on a builder / configuration interface. This will give us freedom to add new modification opportunities over time.
On 2 mai 2011, at 13:10, Gordon Yorke wrote:
> If we go with initialization events everyone would be best served by preCreate/postCreate events that are generic and offer a bit more flexibility for the users.
>
> public interface EntityMangerFactoryCustomizer (
> void preCreate(EntityManagerFactory emf);
> void postCreate(EntityManagerFactory emf);
> }
>
> --Gordon
>
> Emmanuel Bernard wrote:
>>
>> I am not entirely clear about the use case we are trying to address.
>> 1. Having the ability to programmatically define named queries at EMF initialization time
>> 2. Having the ability to programmatically define named queries and add them dynamically during the life time of the EMF (ie after the EMF has been created)
>>
>> I can see the reason to address 1. I have not found a use case for 2., someone has something in mind?
>>
>> If we want to resolve 1. I'd prefer an approach like Gordon was hinting at.
>>
>> We could let people pass to the persistence unit configuration a class name whose responsibility is to create these named queries programamtically
>>
>> interface QueryConfigurator {
>> void defineNamedQueries(QueryManager qm);
>> }
>>
>> interface QueryManager {
>> CriteriaBuilder getCriteriaBuilder();
>> Query createQuery(String qlString);
>> ...
>> QueryManager addNamedQuery(String name, TypedQuery<T> query);
>> }
>>
>>
>> //user class
>> class MyAppQueriesDefinition implements QueryConfigurator {
>> //no arg constructor required
>>
>> public void defineNamedQueries(QueryManager qm) {
>> TypedQuery<Integer> tq = qm.createQuery("SELECT e.seniority FROM Employee e WHERE e.seniority > 10", Integer.class);
>> qm.addNamedQuery("Employee_Seniority", tq);
>>
>> //build Criteria query
>> TypedQuery<Integer> tq2 = qm.createQuery(criteriaQuery);
>> tq2.setMaxResults(20);
>> qm.addNamedQuery("get_top_20_chefs", tq2);
>> }
>> }
>>
>> //user persistence.xml
>>
>> <persistence-unit ...>
>> ...
>> <properties>
>> <property name="javax.persistence.query.queryConfigurator" value="com.acme. MyAppQueriesDefinition"/>
>> </properties>
>> </persistence-unit>
>>
>>
>> Also if we end up working on a fluent API to programmatically define a persistence unit, this could fit in as well as part of a more general purpose way to programmatically customize configuration.
>>
>> Emmanuel
>>
>> On 12 avr. 2011, at 20:43, Linda DeMichiel wrote:
>>
>>
>>> We've received suggestions to the effect that it would be useful if
>>> queries could be created dynamically (e.g., at initialization time)
>>> and then be assigned names so that they could be used for execution
>>> later.
>>>
>>> These queries would have the same scope as other named queries,
>>> and be associated with the persistence unit.
>>>
>>> For example:
>>>
>>> TypedQuery<Integer> tq = em.createQuery("SELECT e.seniority FROM Employee e WHERE e.seniority > 10", Integer.class);
>>> emf.addNamedQuery("Employee_Seniority", tq);
>>>
>>> Any configuration of the query object (except for actual parameter
>>> binding) specified when the query was added as a named query would be
>>> retained as part of the named query. [I.e., this would include
>>> configuration information like setMaxResults, setHint, setFlushMode,
>>> setLockMode, result set mapping information, and information
>>> registered about stored procedure parameters...]
>>>
>>> When the query is executed, information that is settable by means
>>> of the Query API can be overridden. Information that is overridden
>>> does not affect the named query as registered with the EMF, and
>>> thus does not affect subsequent Query objects created by means
>>> of the name via the EntityManager createNamedQuery method.
>>>
>>>
>>> Linda
>>>
>>
>>