web-dev-qa-db-fra.com

Spring-boot: impossible d'utiliser la persistance

Je suis au bout de quelques jours et, même si j'apprends beaucoup, je commence à désespérer. 

J'ai essayé toutes les suggestions sur cette excellente question: 

Aucun fournisseur de persistance pour EntityManager nommé

J'ai eu ce travail à un moment en utilisant la classe omniprésente HibernateUtil, mais on m'a dit de passer à un style simple JPA ici:

Suggestions d'amélioration de la méthode du contrôleur Spring RESTful

Malheureusement, l'injection de haricot ne fonctionnait pas correctement au printemps. Voici ma tentative:

Spring JPA (Hibernate) Aucun haricot qualifiant de type: javax.persistence.EntityManagerFactory

Après beaucoup de travail dans cette voie, je me suis retrouvé avec un gestionnaire d'entités nul. J'ai trouvé cela et j'ai commencé à penser que cela ne pourrait pas fonctionner:

Utilisation de JPA2 dans Tomcat 6: @PersitenceContext ne fonctionne pas, EntityManager a la valeur null

Il me semble qu'EntityManagerFactory doit absolument être un bean, quel que soit le contexte créé par spring-boot, mais ... peu importe. Je penserais qu'au moins cela fonctionnerait:

Lancement de l'application:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Manette:

@Controller
public class GetController {

    private static final String PERSISTENCE_UNIT_NAME = "cpJpaPu";  

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public @ResponseBody User getUser(@RequestParam(value="id", required=true) int id) {
        User user = null;

        EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = emf.createEntityManager();
        UserDAO userDao = new UserDAO();
        userDao.setEntityManager(em);
        user = userDao.load(id);

        return user;
    }
}

DAO:

public class UserDAO {

    public EntityManager entityManager;

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }   

    public void insert(User user) {
        entityManager.persist(user);
    }

    public User load(int id) {
        return entityManager.find(User.class, id);
    }
}

/src/main/resources/persistence.xml:

<persistence xmlns="http://Java.Sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence http://Java.Sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <persistence-unit name="cpJpaPu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.mydomain.User</class>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.show_sql" value="false"/>
      <property name="hibernate.connection.username" value="user"/>
      <property name="hibernate.connection.password" value=""/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/mydb"/>
    </properties>
  </persistence-unit>
</persistence>

Et ça ne marche pas:

javax.persistence.PersistenceException: No Persistence provider for EntityManager named cpJpaPu
    javax.persistence.Persistence.createEntityManagerFactory(Persistence.Java:61)
    javax.persistence.Persistence.createEntityManagerFactory(Persistence.Java:39)
    com.mydomain.GetController.getUser(GetController.Java:25)
    Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    Sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    Java.lang.reflect.Method.invoke(Unknown Source)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.Java:214)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:748)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:689)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:947)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:878)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:946)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.Java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:822)
    javax.servlet.http.HttpServlet.service(HttpServlet.Java:728)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:108)

--- Ajout d'informations ---

POM:

<?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>com.mygroup</groupId>
    <artifactId>myartifact</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>0.5.0.M6</version>
    </parent>

    <dependencies>
        <!--  Spring framework -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--  Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <!-- Must override version or face stack traces -->
            <version>4.3.0.Final</version>
        </dependency>

        <!-- Spring ORM, works with Hibernate -->   
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-orm</artifactId>
        </dependency>

        <!--  Spring implementation of Jackson for RESTful JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>         
        </dependency>

        <!--  JDBC -->
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.1-901.jdbc4</version>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

        <!-- Prevent logging conflicts -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
            <scope>compile</scope>
            <exclusions>                
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions> 
        </dependency>
    </dependencies>

    <properties>
        <start-class>com.cloudfordev.controlpanel.Application</start-class>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>          
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
12
Lurk21

Cette question a été répondue avec une architecture bien meilleure ici:

Spring JPA (Hibernate) Aucun haricot qualifiant de type: javax.persistence.EntityManagerFactory

1
Lurk21

spring Boot ne lit pas le fichier persistence.xml par défaut, voir le document ici

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html

donc si vous voulez continuer à utiliser le fichier persistence.xml, ajoutez simplement le code ci-dessous dans votre classe AppConfig

@Bean
public LocalEntityManagerFactoryBean entityManagerFactory(){
     LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
    factoryBean.setPersistenceUnitName("cpJpaPu");
    return factoryBean;
}
6
vedat

Certaines fonctionnalités de JPA ne fonctionnent malheureusement que dans la configuration XML, mais je ne vois rien de tel dans la vôtre. Je ne pense pas que persistence.xml soit chargé par défaut, alors c'est probablement le problème. Alors, pourquoi ne pas suivre le flux et utiliser Java et application.properties pour configurer le gestionnaire d'entités? L'exemple JPA de Spring Boot contient tout ce dont vous avez besoin pour commencer. Il utilise Spring Data JPA, alors que votre code utilise uniquement les API JPA, mais vous pouvez facilement revenir à ce niveau en supprimant simplement les dépendances Spring Data de l'exemple.

Les instantanés Spring Spring récents ont une fonctionnalité qui vous permet de créer votre propre LocalEntityManagerFactoryBean de sorte que vous puissiez ajouter une configuration XML personnalisée, mais vous devrez faire toute la configuration JPA manuellement si vous avez besoin d'un EntityManager personnalisé.

N.B. vous n'utilisez pas vraiment l'injection de dépendance dans votre contrôleur - pourquoi ne pas simplement injecter le UserDao?

1
Dave Syer

Le fichier persistence.xml doit se trouver dans le répertoire META-INF.

/src/main/resources/META-INF/persistence.xml

1
xi.lin

J'ai résolu ce problème après avoir supprimé tous les dossiers hibernate-core du répertoire ci-dessous: .m2\repository\org\hibernate\hibernate-core

et reconstruit mes projets.

Maintenant, cela fonctionne très bien sous Spring Boot 2.0.4.RELEASE. Et je suis sûr qu'il charge le fichier principal/resources/META-INF/persistence.xml sans injecter le bean LocalEntityManagerFactoryBean.

Avant de les supprimer, le dossier ci-dessus contient 4 versions de hibernate-core. Ils sont "4.3.6"/"5.0.12"/"5.2.17"/"5.3.4".

Après que je les ai supprimés, il y a "5.0.12"/"5.2.17"/"5.3.4" après la reconstruction de mes projets.

Et quand je me suis plongé dans cette affaire, j’ai trouvé que le dossier "hibernate-core-5.2.17.Final.jar" de l’ancien "5.2.17" était plus grand que la normale et qu’il ne contenait pas de "hibernate-core-5.2.17". .Final.jar.sha1 ".

Cela peut donc être dû à un réseau médiocre ou à un miroir médiocre.

0
capcom923