2009-05-23 14 views
25

L'une des principales raisons pour lesquelles j'utilise Hibernate est qu'il offre la possibilité de passer à une autre base de données sans avoir à réécrire du code. Mais jusqu'à présent, je n'avais pas trouvé de moyen de définir des vues supplémentaires sur les tables auxquelles mes entités Hibernate sont associées; J'utilise toujours des scripts SQL simples pour cela. Existe-t-il un moyen plus élégant de définir des vues sur des tables gérées par Hibernate?Des façons élégantes de gérer les vues de base de données sur les entités hibernate?

Idéalement, je voudrais utiliser HQL ou une autre méthode générique pour faire le travail, de sorte que je n'ai pas à m'inquiéter de l'incompatibilité de mes scripts SQL avec d'autres types de bases de données. S'il existe un moyen de le faire, un deuxième problème consisterait à obtenir des instances en lecture seule «synthétiques» à partir de ces vues, ce qui devrait faciliter le transfert des données agrégées dans une interface utilisateur.

EDIT:

Il semble que si je ne faisais pas le problème assez clair, donc voici ce que je suis en train de faire: je veux écrire du code qui est indépendant de la base de données utilisée. Puisque j'utilise Hibernate, je devrais simplement changer le fichier de configuration du dialecte et utiliser un autre SGBD.

Question: comment créer vues sur mes entités mise en veille prolongée sans compter sur un dialecte SQL spécifique (pour garder tout portable), ou même HQL? Et si c'est possible, puis-je utiliser HQL pour interroger également ces vues, c'est-à-dire pour créer des entités agrégées en lecture seule? Y at-il un plug-in Hibernate supplémentaire pour m'aider avec ça? Vous n'avez encore rien trouvé ...: -/

Répondre

22

Hibernate crée pas automatiquement les vues pour vous, car chaque dialecte ne supporte qu'un sous-ensemble limité de la langue des données définition (DDL) de la base de données sous-jacente. Fondamentalement, il supporte assez DDL pour générer un schéma de travail, mais pas assez pour gérer la création d'objets "supplémentaires" comme les vues.

Tout n'est pas perdu, cependant. Hibernate vous donne la possibilité de créer (et de déposer) des objets de base de données supplémentaires vous-même dans les fichiers de mappage XML, et ces objets peuvent être étendus à un dialecte particulier.Par exemple, je pourrais avoir une application comme ceci:

<hibernate-mapping> 
    <class name='com.mycompany.myproduct.Customer' table='tbl_customer'> 
    <id name='id' column='customer_id'> 
     <generator class='native'/> 
    </id> 
    <property name='name' length='50' unique='true' not-null='true' /> 
    </class> 

    <database-object> 
    <create>create or replace view read_only_cust...</create> 
    <drop>drop view read_only_cust</drop> 
    <dialect-scope name='org.hibernate.dialect.Oracle9Dialect' /> 
    </database-object> 
</hibernate-mapping> 

Vous êtes libre de créer ce point de vue supplémentaire que vous voulez en ajoutant plus de sections « base de données objet ». Vous devez écrire le code SQL (DDL) vous-même pour chaque base de données que vous voulez prendre en charge, mais comme ils sont limités au dialecte, Hibernate n'exécutera que le code SQL pour le dialecte choisi lors de l'exportation du schéma.

+1

Merci! Cela semble être le seul moyen de le faire. Encore mieux que d'avoir des scripts SQL qui traînent ... :-) –

0

Pouvez-vous déclarer les vues directement dans la base de données? Ensuite, vous pouvez simplement sélectionner directement à partir des vues. Regardez chapter 10.4.4 of the Hibernate manual

Cela devrait vous permettre de sélectionner à partir de la vue de la base de données et obtenir Hibernate pour hydrater automatiquement les données dans vos entités.

Bien sûr, une vue ne prend aucun paramètre. Hibernate 3 est censé prendre en charge les procédures stockées, mais je l'ai utilisé.

+0

Merci pour votre réponse. Il y a un petit malentendu ici (je vais éditer la question et la rendre plus explicite): il ne s'agit pas d'utiliser SQL pour récupérer des entités Hibernate, mais plutôt l'inverse: comment déclarer des vues * sur * des entités hibernate sans utiliser SQL (qui dépend du système DB utilisé et donc contredit l'iddea basique d'être indépendant du SGBD, à mon humble avis). –

0

Que voulez-vous dire par "créer vue"? Je sais ce que cela signifie dans un contexte purement DB - mais ce n'est pas ce que vous voulez dire - n'est-ce pas?

Vous pouvez mapper de nouvelles classes Java vers les mêmes tables pour créer une "vue" ou vous pouvez utiliser HQL pour sélectionner un sous-ensemble des colonnes mappées par d'autres classes persistantes.

HTH

12

eu le même problème et trouvé la solution suivante dans la mise en veille prolongée doucmentation de:

Il n'y a pas de différence entre une vue et une table de base pour un mapping Hibernate . Cela est transparent au niveau de la base de données , bien que certains SGBD ne prennent pas en charge les vues correctement, en particulier avec les mises à jour. Parfois, vous souhaitez utiliser une vue, mais vous ne pouvez pas en créer une dans la base de données (c'est-à-dire avec un schéma hérité). Dans ce cas, vous pouvez mapper une immuable et en lecture seule entité à une expression de sous-requête SQL donnée :

<class name="Summary"> 
    <subselect> 
     select item.name, max(bid.amount), count(*) 
     from item 
     join bid on bid.item_id = item.id 
     group by item.name 
    </subselect> 
    <synchronize table="item"/> 
    <synchronize table="bid"/> 
    <id name="name"/> 
    ... 
</class> 

https://docs.jboss.org/hibernate/stable/core/manual/en-US/html_single/#mapping-declaration

Questions connexes