web-dev-qa-db-fra.com

Des moyens élégants de gérer les vues de base de données sur des entités en veille prolongée?

Hibernate est l'une des principales raisons pour lesquelles il offre la possibilité de basculer vers une autre base de données sans avoir à réécrire le code.

Mais jusqu'à présent, je ne trouvais pas un bon moyen de définir des vues supplémentaires sur les tables auxquelles mes entités d'hibernation correspondaient; J'utilise toujours des scripts SQL simples pour cela. Existe-t-il un moyen plus élégant de définir des vues sur les tables gérées par Hibernate?

Idéalement, j'aimerais utiliser HQL ou une autre méthode générique pour faire le travail, afin de ne pas avoir à 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 serait alors d'obtenir des instances «synthétiques» en lecture seule à partir de ces vues, ce qui faciliterait grandement l'intégration des données agrégées dans une interface utilisateur.

MODIFIER:

Il semble que le problème ne soit pas suffisamment clair, alors voici ce que j'essaie de faire: je veux écrire du code indépendant de la base de données utilisée. Depuis que j'utilise hibernate, il me suffirait de modifier le fichier de configuration du dialecte pour pouvoir utiliser un autre SGBD.

Question: comment créer views sur mes entités d'hibernation without en s'appuyant sur un dialecte SQL spécifique (pour que tout soit portable), ou même sur HQL? Et si cela 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? Existe-t-il un plug-in Hibernate supplémentaire pour m'aider? Je n'ai rien trouvé jusqu'ici ...: - /

25
Roland Ewald

Hibernate ne créera pas automatiquement les vues pour vous, car chaque dialecte ne prend en charge qu'un sous-ensemble limité du langage de définition de données (DDL) de la base de données. Fondamentalement, il prend en charge suffisamment de DDL pour générer un schéma fonctionnel, mais pas assez pour gérer la création d’objets "supplémentaires" tels que des vues.

Cependant tout n'est pas perdu. Hibernate vous donne la possibilité de créer (et de supprimer) 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 un mapping 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 toutes les vues supplémentaires souhaitées en ajoutant d'autres sections "objet de base de données". Vous devez écrire le code SQL (DDL) vous-même pour chaque base de données que vous souhaitez prendre en charge, mais comme ils sont concernés par le dialecte, Hibernate n'exécutera le code SQL que pour le dialecte choisi lors de l'exportation du schéma.

22
Rob H

Avait le même problème et a trouvé la solution suivante dans la double veille hibernée:

Il n'y a pas de différence entre une vue Et une table de base pour un mappage Hibernate . Ceci est transparent au niveau de la base de données , Bien que certains SGBD ne supportent pas correctement les vues, en particulier Avec mises à jour. Parfois, vous souhaitez utiliser Une vue, mais vous ne pouvez pas en créer un Dans la base de données (c'est-à-dire avec un schéma Hérité). Dans ce cas, vous pouvez mapper une expression Immuable et en lecture seule à une expression Donnée SQL:

<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

12
Dominik

Pouvez-vous déclarer les vues directement dans la base de données? Ensuite, vous pouvez simplement sélectionner directement dans les vues. Consultez le chapitre 10.4.4 du manuel d'Hibernate

Cela devrait vous permettre de SÉLECTIONNER dans la base de données et d’obtenir que Hibernate hydrate automatiquement les données dans vos entités.

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

0
Ben Hammond

Qu'entendez-vous par "créer une vue"? Je sais ce que cela signifie à partir d'un contexte DB pur - mais ce n'est pas ce que vous voulez dire - n'est-ce pas? 

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

HTH

0
Tom