David W
David W

Reputation: 61

Consider defining a bean of type EntityManagerFactory Spring boot

I am using Spring boot and am running in this error:

A component required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.

Action:

Consider defining a bean of type javax.persistence.EntityManagerFactory in your configuration.

I dont know whay I should do, because I do everything based on a course

I used @PersistanceUnit to injection EntityManagerFactory

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>pl.javastart</groupId>
    <artifactId>spring-jpa-boot2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-jpa-boot2</name>
    <description>Spring boot app</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
package pl.javastart.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Repository;
import pl.javastart.model.Book;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceUnit;

@Repository
public class BookDaoImpl implements BookDao {


    @PersistenceUnit
    private EntityManagerFactory emFactory;


    public BookDaoImpl(){

    }

    @Override
    public void save(Book book) {
        EntityManager entityManager = emFactory.createEntityManager();
        EntityTransaction tx = entityManager.getTransaction();
        tx.begin();
        entityManager.persist(book);
        tx.commit();
        entityManager.close();
    }

    @Override
    public Book get(Long id) {
        EntityManager entityManager = emFactory.createEntityManager();
        Book book = entityManager.find(Book.class, id);
        entityManager.close();
        return book;
    }
}
package pl.javastart;

import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import pl.javastart.dao.BookDao;
import pl.javastart.model.Book;

@Configuration
@ComponentScan
public class SpringJpaApplication {
    public static void main(String[] args) throws InterruptedException {


        ConfigurableApplicationContext ctx = SpringApplication.run(SpringJpaApplication.class, args);
        BookDao dao = ctx.getBean(BookDao.class);
        Book book = new Book("1234567890468", "Spring is so cool", "Javastart");
        dao.save(book);
        Thread.sleep(5000);
    }
}

How do I solve this?

Upvotes: 2

Views: 10563

Answers (2)

David W
David W

Reputation: 61

I added two depedency to maven:

<dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>

Everything works

Upvotes: 1

Milton BO
Milton BO

Reputation: 608

Your configuration is fixed between JPA server configuration and Spring Boot.

In Spring Boot you need to create a datasource bean that will be used by the all application. Normally you don't need to use the EntityManager neither EntityManagerFactory, this because the server and Spring Data will create both, and you only need to use the repositories created by Spring and Services you will implement.

Here is a normal configuration of Spring Boot application.

@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"package.where.are.your.repositorios.and.services"})
@EntityScan(basePackages = "package.where.are.your.entities")
@EnableJpaRepositories(basePackages = "package.where.are.your.repositories", entityManagerFactoryRef = "entityManagerFactory")
@EnableTransactionManagement
public class RepositoryConfiguration {

    @Bean
    public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
        // Here you can create your datasource using application.properties configuration or inject the datasource from the server application.
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        bean.setJndiName("JNDI_IN_YOUR_SERVER");
        bean.setProxyInterface(DataSource.class);
        bean.setLookupOnStartup(true);
        bean.afterPropertiesSet();
        return (DataSource) bean.getObject();
    }

}

This is a classic configuration of the Spring Data to enable you implement repositories.

One repository example:

@Repository
public interface BuserRepository extends JpaRepository<Buser, Long> {

    @Query("SELECT t FROM Buser t WHERE t.username = :username")
    Optional<Buser> findByUsername(@Param("username") String username);

}

If you want to save some new object or update in database, all of these is already implemented in JpaRepository class of Spring or there are others classes to extend.

Please read more about this here:

https://spring.io/guides/gs/accessing-data-jpa/

Upvotes: 0

Related Questions