2016-06-12 4 views
4

Cette question est spécifique au commerce de broadleaf. Je dois charger une entité dans une méthode statique. Puisque l'injection d'entityManager n'aiderait pas (comme je ne peux pas y accéder dans une méthode statique), je ne suis pas capable de charger l'entité.Comment obtenir une instance statique de entityManager dans broadleaf?

J'ai essayé d'utiliser Persistence.createEntityManagerFactory, mais cela n'aide pas. Voici mon exemple de code.

Query query = Persistence.createEntityManagerFactory("blPU").createEntityManager().createQuery("some query"); 
List results = query.getResultList(); 

L'erreur que je reçois: -

javax.persistence.PersistenceException: No Persistence provider for EntityManager named blPU 

Pour les cas où je dois l'utiliser normalement dans les méthodes d'instance, entityManager fonctionne comme un charme:

@PersistenceContext(unitName="blPU") 
protected EntityManager em; 

donc je suppose que ce n'est pas un problème de chemin de classe. Toute aide serait géniale.

+0

Vous pouvez injecter un entityManager statique, mais il ne semble pas une bonne idée. Vous pouvez voir des exemples et des alternatives ici http://stackoverflow.com/questions/8621124/jpa-entitymanager-static-or-instance et ici http://stackoverflow.com/questions/7007205/static-access-to-entity- manager-in-spring-et-insolite-architecture –

Répondre

1

Si vous n'avez pas vraiment besoin d'écrire votre requête dans un contexte statique mais souhaitez accéder à une entité dans une méthode statique, je vais vous donner la suggestion de trouver simplement une instance existante d'un EJB via CDI- contexte avec le code générique suivant:

public class Util { 
    private static <T> T lookUpClassInBeanManager(Class<T> clazz) { 
     BeanManager bm = CDI.current().getBeanManager(); 
     Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next(); 
     CreationalContext<T> ctx = bm.createCreationalContext(bean); 
     return (T) bm.getReference(bean, clazz, ctx); 
    } 

    public static YourDaoClass lookUpYourDaoClass() { 
     return lookUpClassInBeanManager(YourDaoClass.class); 
    } 
} 

Votre DaoClass ressemble à ça:

@Stateless 
public class YourDaoClass { 

    @PersistenceContext(unitName = "blPU", type = PersistenceContextType.TRANSACTION) 
    protected EntityManager em; 

    public <T> List<T> getEntityListByType(Class<T> clazz) { 
     TypedQuery<T> query = em.createQuery("select entity from "+ clazz.getSimpleName() +" entity", clazz); 
     return query.getResultList(); 
    } 
} 

Dans une méthode statique cela peut être utilisé comme ça:

public static void tryEJBinStaticContext() { 
    YourDaoClass dao = Util.lookUpYourDaoClass(); 
    List<SomeEntity> list = dao.getEntityListByType(SomeEntity.class); 
} 
0

Pour être clair, c'est une mauvaise idée d'obtenir EntityManagerFactory sur le Peristence.createEntityManagerFactory à l'intérieur du conteneur d'entreprise, utilisez la capacité du conteneur à la place. Si vous avez besoin de Peristence.createEntityManagerFactory en dehors du récipient disons, pour le test seulement ou pour d'autres raisons. Vous devez créer le contexte Java SE JPA, j'ai créé ce example project pour expliquer comment le faire pour le test JPA.

Voici quelques avis de projet pour une meilleure compréhension, si vous envisagez de le faire par vous-même.

La partie la plus importante est de créer un seul persistence.xml, évitez d'en créer un autre pour les tests, écrasez les paramètres de votre persistence.xml à la place. Cela devrait être suffisant pour vous persistence.xml:

<persistence-unit name="application-ds" transaction-type="JTA"> 
    <jta-data-source>java:/youApplication</jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
</persistence-unit> 

Dans l'exemple projet, j'ajouter des propriétés pour la génération de base de données, mais cela peut-être vous n'avez pas besoin d'une autre manière de vous préparer la base de données.

Pour créer votre EntityManagerFactory, passer le nom de l'unité de persistance (ce qui est important), ainsi que les propriétés carte à Persistence.createEntityManagerFactory. Cette étape vous permet de configurer le fournisseur de persistance pour Java. Il existe certaines limitations, d'abord nous n'avons pas de JTA et JPA ne peut pas découvrir automatiquement les classes d'entités. propriétés Voici les plus importantes:

properties.put("javax.persistence.transactionType", "RESOURCE_LOCAL"); 
properties.put("javax.persistence.provider", "org.hibernate.jpa.HibernatePersistenceProvider"); 
properties.put("javax.persistence.jtaDataSource", null); 
properties.put("hibernate.archive.autodetection", "class"); 

L'astuce suivante est de savoir comment injecter ou fournisseur de persistance dans la ejb et Mockito est la solution.Code premier:

@InjectMocks 
private UserDao dao; 

@Spy 
private EntityManager em; 

@Before 
public void prepare() { 
    em = JpaProvider.instance().getEntityManager(); 
    initMocks(this); 
} 

Explication: Mockito est utilisée pour injecter le gestionnaire d'entités dans le ejb. Marquez EntityManager comme objet espion et initialisez-le dans la méthode de test @Before, puis appelez le initMocks dans la classe de test qui est tout. Enfin, n'oubliez pas de créer et de valider des transactions, car vous n'avez pas de conteneur pour le faire pour vous.

0

Une réponse spécifique Feuillu (si vous avez besoin d'un blPU EntityManager) est d'utiliser:

GenericEntityDaoImpl.getGenericEntityDao().getEntityManager();