Spring Data JPA - Consider defining a bean named 'entityManagerFactory' in your configuration
I am developing an application in Spring, using Tomcat, Mysql5, Java8... The problem is that I cannot deploy it, due to "required bean 'entityManagerFactory' not found" problem. I have developed this project with my coworkers but they can perfectly deploy it with any problems, even if I copy-paste the same project in Spring Tool Suite. How can be possible? Error:
2016-12-15 17:41:12.777 WARN 3676 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controlador': Unsatisfied dependency expressed through field 'usuarioDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usuarioRepository': Cannot create inner bean '(inner bean)#59e43e8c' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#59e43e8c': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available 2016-12-15 17:41:12.783 INFO 3676 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat 2016-12-15 17:41:12.807 WARN 3676 --- [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 2016-12-15 17:41:12.826 INFO 3676 --- [ main] utoConfigurationReportLoggingInitializer : Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 2016-12-15 17:41:12.940 ERROR 3676 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Field usuarioDao in es.uc3m.tiw.Controladores.Controlador required a bean named 'entityManagerFactory' that could not be found. Action: Consider defining a bean named 'entityManagerFactory' in your configuration.
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>es.uc3m.tiw</groupId> <artifactId>Cliente</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>Cliente</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Here is my repository
package es.uc3m.tiw.Daos; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import es.uc3m.tiw.dominios.Usuario; public interface UsuarioRepository extends JpaRepository<Usuario, Long> { List<Usuario> findAll(); Usuario findByNombre(String nombre); }
Here is my controller
package es.uc3m.tiw.Controladores; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import es.uc3m.tiw.Daos.AdministradorRepository; import es.uc3m.tiw.Daos.UsuarioRepository; import es.uc3m.tiw.dominios.Administrador; import es.uc3m.tiw.dominios.Usuario; @RestController public class Controlador { @Autowired private UsuarioRepository usuarioDao; private AdministradorRepository administradorDao; @RequestMapping(value="/registroUsuario", method = RequestMethod.POST) public @ResponseBody Usuario registrarUsuario(@RequestBody Usuario usuarioARegistrar){ usuarioDao.save(usuarioARegistrar); //guardar, editar, borrar, findbyOne(Primary key) son métodos que vienen implementados ya en el CrudRepository return usuarioARegistrar; } @RequestMapping(value="/editarUsuario", method = RequestMethod.POST) public @ResponseBody Usuario editarUsuario(Usuario usuarioAEditar){ usuarioAEditar.setNombre(usuarioAEditar.getNombre()); usuarioAEditar.setApellidos(usuarioAEditar.getApellidos()); usuarioAEditar.setCiudad(usuarioAEditar.getCiudad()); usuarioAEditar.setEmail(usuarioAEditar.getEmail()); usuarioAEditar.setPassword(usuarioAEditar.getPassword()); usuarioDao.save(usuarioAEditar); return usuarioAEditar; } @RequestMapping(value="/eliminarUsuario", method = RequestMethod.DELETE) public @ResponseBody Usuario eliminarUsuario(Usuario usuarioAEliminar){ usuarioDao.delete(usuarioAEliminar); return usuarioAEliminar; } @RequestMapping(value="/validar" ,method = RequestMethod.POST) public @ResponseBody Usuario loginUsuario(@RequestBody Usuario usuarioPendiente){ Usuario usuarioLogeado = null; List <Usuario> usuarios = usuarioDao.findAll(); usuarioLogeado = comprobarUsuario(usuarios, usuarioPendiente.getEmail(),usuarioPendiente.getPassword()); return usuarioLogeado; } @RequestMapping(value="/verPerfilUsuario", method = RequestMethod.GET) public @ResponseBody Usuario verPerfilUsuario(Usuario usuarioAMostrar){ usuarioAMostrar.getNombre(); usuarioAMostrar.getApellidos(); usuarioAMostrar.getCiudad(); usuarioAMostrar.getEmail(); usuarioAMostrar.getPassword(); return usuarioAMostrar; } @RequestMapping(value="/loginAdministrador" ,method = RequestMethod.POST) public @ResponseBody Administrador loginAdministrador(@RequestBody Administrador administradorPendiente){ Administrador administradorLogeado = null; List <Administrador> administradores = administradorDao.findAll(); administradorLogeado = comprobarAdministrador(administradores, administradorPendiente.getEmail(),administradorPendiente.getPassword()); return administradorLogeado; } private Usuario comprobarUsuario( List<Usuario> usuarios, String email, String password) { Usuario u = null; for (Usuario usuario : usuarios) { if (email.equals(usuario.getEmail()) && password.equals(usuario.getPassword())){ u = usuario; break; } } return u; } private Administrador comprobarAdministrador( List<Administrador> administradores, String email, String password) { Administrador ad = null; for (Administrador administrador : administradores) { if (email.equals(administrador.getEmail()) && password.equals(administrador.getPassword())){ ad = administrador; //break; } } return ad; } }
Application.properties
server.port=8010 spring.datasource.url=jdbc:mysql://localhost:3306/tiw spring.datasource.username=root spring.datasource.password=admin spring.datasource.driver-class-name = com.mysql.jdbc.Driver spring.jpa.hibernate.ddl-auto = update
Entity
package es.uc3m.tiw.dominios; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="USUARIOS") public class Usuario implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; @Column(length = 25) private String nombre; @Column(length = 25) private String apellidos; @Column(length = 25) private String ciudad; @Column(length = 25, nullable = false, unique = true) private String email; @Column(length = 25, nullable = false) private String password; public Usuario() { } public Usuario(long id, String nombre, String apellidos, String ciudad, String password, String email) { super(); this.id = id; this.nombre = nombre; this.apellidos = apellidos; this.ciudad = ciudad; this.password = password; this.email = email; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public String getCiudad() { return ciudad; } public void setCiudad(String ciudad) { this.ciudad = ciudad; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Here is my main
package es.uc3m.tiw; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ClienteSpringApplication { public static void main(String[] args) { SpringApplication.run(ClienteSpringApplication.class, args); } }
213 Answers
In my case, I had the wrong dependency: spring-data-jpa
. when I changed to spring-boot-starter-data-jpa, it solved the problem.
I didn't have to add any annotation @Repository
nor @EnableJpa
etc.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
1You are missing repository configuration, as you have to configure it using @Repository
,
Following is incorrect,
public interface UsuarioRepository extends JpaRepository<Usuario, Long> {
Rather it should be configured as repository as follows,
@Repository public interface UsuarioRepository extends JpaRepository<Usuario, Long> {
This will make it a bean to be scanned and treat it as a repository and then your following code should work as expected as well,
@Autowired private UsuarioRepository usuarioDao;
0I had exact same issue. When I checked maven build log I have realised that there was an error about hibernate packages complaining about "invalid LOC header (bad signature)". I solved by deleting sub directories under .m2\repository\org\hibernate\hibernate-core and recompiling my project.
1In your ClienteSpringApplication
you only have the @SpringBootApplication
annotation, wich is the equivalent of @Configuration
, @EnableAutoConfiguration
and @ComponentScan
. What you are missing is the @EnableJpaRepositories
annotation.
package es.uc3m.tiw; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableJpaRepositories public class ClienteSpringApplication { public static void main(String[] args) { SpringApplication.run(ClienteSpringApplication.class, args); } }
If it doesn't work like that try adding also the package of your repository:
@EnableJpaRepositories("es.uc3m.tiw.dominios")
check that you added @Repository annotation on JpaRepository Check that you make all entity Setter and Getter clean and build then run.
pom.xml needs to be updated and it works for me:
I added the following dependency:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency>
I faced the same issue some time back and in my case the package declaration in connection configuration was wrong. So like others said, either check the annotations in SpringBootApplication class or the configurations in your connectionconfiguration class
@Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "someEntityManagerFactory", transactionManagerRef = "someTransactionManager", **basePackages = {"com.pack.some.database.repository"})** public class MyConnectionConfiguration {
In my case, I was missing Hibernate Entity Manager dependency,
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.2.3.Final</version> </dependency>
because I have had only this one (Hibernate Core):
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.1.4.Final</version> </dependency>
Furthermore solved adding this dependency:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency>
as suggested here: link.
Check persistence-api in pom file and try to change with hibernate-jpa-2.1 which is a part of spring-boot-started-data-jpa jar
In my case was the h2-1.4.193.jar, that contains the Driver class but it can't be read (very odd, may be is corrupted), as you can see: Driver class from h2-1.4.193
So, you can update de spring-boot-starter-parent to 1.5.3.RELEASE (or newer) or override the managed version of your h2 dependency.
Be careful with jars dependencies loaded by Maven, in my case hibernate-core.jar was corrupted, once I removed and install that dependency the project runs ok. cheers.
In my case, the problem was incompatible versions between JPA nad Spring Boot version
After trying a dozen things, I finally gave up and added a bean to my config like it says to do, with a DataSource
variable named dataSource
which gets @Autowired
in the constructor. Then it wanted another bean that I also added.
Here is the final config, don't forget to replace the repository.package.location
text with the package location of your repository:
@Configuration public class JpaConfiguration { private final DataSource dataSource; public JpaConfiguration(DataSource dataSource) { this.dataSource = dataSource; } @Bean public EntityManagerFactory entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("repository.package.location"); factory.setDataSource(dataSource); factory.afterPropertiesSet(); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; } }
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoa2ppZ2WDd32OrKeroZ6ceqWt05pko6iRYrCwutKim56qXZmyp7XNoqWgZZFir6atzWalmqWVmXqmutOiq7KlkaOuqLHRn5icrJ%2Bnxm61zWawqK2i