Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

By all means, when writing a concrete action component that needs an Entity Manager, inject the exact entity manager that you need.

However, if you are writing a framework component that doesn't know which entity manager its needs until runtime, well you can handle that as well. Here is how it can be done.

We can leverage both the Seam metadata and the metadata of your JPA provider.

Here is the use case:

    EntityManager em = EntityManagers.instance().forClass(someEntity.getClass());

First we need a component utility to find all components of a specific type.

public class ComponentUtil {

    public static List<Component> getComponentsByBeanClass(Class<?> beanClass) {
        List<Component> list = new ArrayList<Component>();

        Context context = Contexts.getApplicationContext();
        String[] names = context.getNames();

        for (String name : names) {
            if (name.endsWith(Initialization.COMPONENT_SUFFIX)) {
                Component component = (Component) context.get(name);
                if (component.getBeanClass().equals(beanClass)) {
                    list.add(component);
                }
            }
        }
        return list;
    }
}

Then we need a jpa utility to find all the classes supported by an entity manager. This example uses Hibernate.

public class HibernateUtil {

    public static Set<String> getEntityNames(EntityManager em) {
        Session session = (Session) em.getDelegate();
        Map map = session.getSessionFactory().getAllClassMetadata();
        return map.keySet();
    }
}

Then we can create our EntityManagers component.

@Name("EntityManagers")
@Scope(ScopeType.APPLICATION)
public class EntityManagers {

    public EntityManager forClass(Class<?> type) {
        return (EntityManager) Component.getInstance(getMap().get(type.getName()));
    }

    private Map<String, String> map;
   
    public Map<String, String> getMap() {
        if (map == null) {
            map = new HashMap<String, String>();
           
            List<Component> list = ComponentUtil
                    .getComponentsByBeanClass(ManagedPersistenceContext.class);

            for (Component component : list) {
                String persistenceContextName = component.getName();
                EntityManager entityManager = (EntityManager) Component
                        .getInstance(persistenceContextName);

                Set<String> entityNames = HibernateUtil.getEntityNames(entityManager);
                for (String name : entityNames) {
                    map.put(name, persistenceContextName);
                }
            }
        }
        return map;
    }

    public static EntityManagers instance() {
        return (EntityManagers) Component.getInstance(EntityManagers.class);
    }
}

Here is our specific implementation.