Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Integração de Spring com EJB

Estou tentando montar um projeto do zero utilizando Spring e EJB com base nos cursos que fiz no Alura.

Fiz toda a minha configuração do meu Datasource via standalone e utilizei as configurações do hibernate via persistence.xml. Criei minhas classe Entity, e as defini no persistence.xml. Até aqui tudo OK, quando inicio meu AS as classes são lidas e as tabelas são criadas.

Minha Entity:

@Entity
public class User {

    @Id
    @Column(nullable = false)
    private String userName;
    private String password;
    @Enumerated(EnumType.STRING)
    private UserRole userRole;
    private Date lastLoginDate;
    (...)

Quando cheguei a parte de criar meu DAO comecou a saga. Primeiro tive problema de incompatibilidade entre o dom4j, consegui resolver desabilitando a opção do Envers na configuração do hibernate. Até então OK!

Criei a classe do DAO como EJB @Stateless, e utilizo a annotation @Inject dentro da minha classe Controller para fazer a injeção do EJB. E quando dou o deploy da applicação, aparece o AS carregando o DAO na memória

Meu DAO:

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import com.fogsoft.myapp.exceptions.DuplicateEntityException;
import com.fogsoft.myapp.model.User;

@Stateless
public class UserDao extends AbstractDao{

    @PersistenceContext
    private EntityManager em;

    public User getUserByUsername(String username) throws IllegalArgumentException{
        if (username.isEmpty()) throw new IllegalArgumentException("Username is required");
        (...)

Console do AS:

(...)
23:04:19,378 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-7) WFLYEJB0473: JNDI bindings for session bean named 'UserDao' in deployment unit 'deployment "MyApp.war"' are as follows:

    java:global/MyApp/UserDao!com.fogsoft.MyApp.dao.UserDao
    java:app/MyApp/UserDao!com.fogsoft.MyApp.dao.UserDao
    java:module/UserDao!com.fogsoft.MyApp.dao.UserDao
    java:global/MyApp/UserDao
    java:app/MyApp/UserDao
    java:module/UserDao

23:04:20,394 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-7) WFLYJCA0005: Deploying non-JDBC-compliant driver class com.mysql.jdbc.Driver (version 5.1)
(...)

Meu Controller:

import javax.inject.Inject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fogsoft.myapp.dao.UserDao;
import com.fogsoft.myapp.model.User;

@Controller
public class UserController {

    @Inject
    private UserDao dao;

    @RequestMapping("/user/add")
    public String addUserForm() {
        return ("User/add");
    }
    (...)

Consigo compilar e dar deploy da minha aplicação. Porem ao acessar a url do meu Spring onde vou fazer o cadastro do registro recebo a seguinte Exception:

Context Path:
/MyApp

Servlet Path:
/user/add

Path Info:
null

Query String:
null

Stack Trace:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'dao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fogsoft.MyApp.dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
    at deployment.MyApp.war//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at deployment.MyApp.war//org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
    at deployment.MyApp.war//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
    at deployment.MyApp.war//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
    at deployment.MyApp.war//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at deployment.MyApp.war//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)

O que estou fazendo de errado? Posso fazer essa integração? O que li sobre o Envers seria algo para auditoria, pode ser a falta desse recurso a causadora desse problema?

Estou utilizando Java8.0_152, Wildfly 10.1, Spring 5.0.2, Hibernate 5.2.12 e MySqlConnector 5.1.31

2 respostas
solução!

é... aí azedou :). O Spring não gerencia a annotation Stateless, como consequência você não vai conseguir pedir essa injeção ali no controller...

Para ser sincero não vejo muito sentido nessa junção, tudo que um ejb te dá você também consegue com um bean gerenciado pelo spring, então pode marcar como @Repository e ser feliz :).

:( Muito obrigado, você colocou a pedra em cima do caixão de uma idéia que já havia dado por morta! hehehehehe Estava tentando pois um amigo que se dizia programador Java, mas hoje estou vendo que é programador NetBeans, havia me dito que utiliza assim no trabalho dele, mass não soube me explicar. Digo programador NetBeans, pois várias duvidas que pergunto a ele, a resposta que tenho é que NetBeans faz sozinho, mas ele não sabe me explicar como se faz em Java.