web-dev-qa-db-fra.com

En quoi Spring Data JPA diffère-t-il d’Hibernate pour les grands projets?

J'ai de la difficulté à décider si je dois rester avec Hibernate pour un nouveau projet, ou si je dois me familiariser avec JPA et la nouvelle implémentation de Spring Data.

Le cadre Spring Data est-il destiné à de grands projets ou de petits projets avec des exigences de requête modestes?

Bien que je voie certainement l'avantage de la réduction de code en utilisant le @Query annotation, que faites-vous pour les requêtes dynamiques? Qu'en est-il lorsque vous souhaitez implémenter une méthode save () assez complexe?

La documentation indique la création d'une interface personnalisée et d'une implémentation que votre référentiel principal implémente, mais que se passe-t-il si vous devez accéder à de super méthodes sur le référentiel crud lui-même? Le référentiel crud implémente celui personnalisé - et non l'inverse. Cela ressemble à une conception étrange.

Je ne suis pas très sûr que ce cadre puisse relever les défis des applications complexes et volumineuses. Je n’ai jamais eu beaucoup de problèmes avec Hibernate, et j’envisage de rester avec le bon vieux fiable plutôt que d’utiliser Spring Data JPA.

Que devrais-je faire? Quelles complications et quels coûts imprévus vais-je rencontrer si j'y vais avec Spring Data JPA?

127
egervari

Alors, spring-data fait un peu plus de magie pour les requêtes complexes. C'est étrange au début et vous le sautez totalement dans la documentation, mais c'est vraiment puissant et utile.

Cela implique de créer un Repository personnalisé et un `RepositoryImpl 'personnalisé, ainsi que d'indiquer à Spring où le trouver. Voici un exemple:

Classe de configuration - pointez sur votre configuration xml toujours nécessaire avec une annotation pointant sur votre paquet repositories (il cherche *Impl cours automatiquement maintenant):

@Configuration
@EnableJpaRepositories(basePackages = {"com.examples.repositories"})
@EnableTransactionManagement
public class MyConfiguration {
}

jpa-repositories.xml - indique à Spring où trouver vos référentiels. Indiquez également à Spring de rechercher des référentiels personnalisés portant le nom de fichier CustomImpl:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<jpa:repositories base-package="com.example.repositories" repository-impl-postfix="CustomImpl" />

</beans>

MyObjectRepository - c'est ici que vous pouvez mettre des méthodes de requête annotées et non annotées. Notez comment cette interface de référentiel étend celle de Custom:

@Transactional
public interface MyObjectRepository extends JpaRepository<MyObject, Integer>, MyObjectRepositoryCustom {

    List<MyObject> findByName(String name);

    @Query("select * from my_object where name = ?0 or middle_name = ?0")
    List<MyObject> findByFirstNameOrMiddleName(String name);
}

MyObjectRepositoryCustom - méthodes de référentiel plus complexes et ne pouvant être gérées avec une simple requête ou une annotation:

public interface MyObjectRepositoryCustom {

    List<MyObject> findByNameWithWeirdOrdering(String name);
}

MyObjectRepositoryCustomImpl - où vous implémentez réellement ces méthodes avec un auto-câblé EntityManager:

public class MyObjectRepositoryCustomImpl implements MyObjectRepositoryCustom {

    @Autowired
    private EntityManager entityManager;

    public final List<MyObject> findByNameWithWeirdOrdering(String name) {
        Query query = query(where("name").is(name));
        query.sort().on("whatever", Order.ASC);
        return entityManager.find(query, MyObject.class);
    }
}

Étonnamment, tout cela est réuni et les méthodes des deux interfaces (et de l'interface CRUD que vous implémentez) s'affichent toutes lorsque vous le faites:

myObjectRepository.

Tu verras:

myObjectRepository.save()
myObjectRepository.findAll()
myObjectRepository.findByName()
myObjectRepository.findByFirstNameOrMiddleName()
myObjectRepository.findByNameWithWeirdOrdering()

Ça marche vraiment. Et vous obtenez une interface pour interroger. spring-data est vraiment prêt pour une grande application. Et plus vous pouvez interroger de requêtes simples ou annotées, mieux vous vous portez.

Tout cela est documenté sur le site Spring Data Jpa .

Bonne chance.

102
sbzoom

J'ai utilisé Spring Data JPA dans des projets de toutes tailles, avec de simples requêtes. Le principal avantage est de ne même pas avoir à utiliser le @Query annotation. Il n'y a rien dans Spring Data qui vous empêche de l'utiliser dans de grands projets et le récent QueryDSLsupport pourrait vous aider. Ceci est un exemple d'utiliser QueryDSL pour cibler Hibernate.

Si vous prévoyez des requêtes complexes et que vous vous sentez à l'aise d'utiliser des objets Hibernate sans JPA, je pense qu'une combinaison alternative pourrait consister à avoir les simples Spring Data Repository à côté des requêtes complexes basées sur Hibernate avec les méthodes spécifiques dont vous pourriez avoir besoin. Il peut être moins fastidieux de tordre une implémentation Hibernate en une structure Spring Data JPA.

11
madth3

Spring JPA vous fournira une grande quantité d’abstractions liées à l’écriture de code SQL et même à des bases de données HQL utilisant la déclaration de méthode de requête. Spring JPA brille par sa génération de requêtes, mais lorsque vous souhaitez une solution purement en veille prolongée, vous pouvez le personnaliser selon vos besoins, car Spring JPA est toujours basé sur la veille prolongée. Consultez la documentation http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html pour plus d'informations.

4
F.O.O