Façons élégantes de gérer les vues de base de données sur les entités hibernate?

L'une des principales raisons pour lesquelles J'utilise Hibernate est qu'il offre la flexibilité de passer à une autre base de données sans avoir à réécrire de code.

Mais jusqu'à présent, je n'ai pas trouvé un bon moyen de définir des vues supplémentaires sur les tables auxquelles mes entités hibernate correspondent; j'utilise toujours des scripts SQL simples pour cela. Est-il un moyen plus élégant de définir des vues sur les tables gérées par 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 que mes scripts SQL soient incompatibles avec d'autres types de bases de données.

S'il y a un moyen de le faire, un deuxième problème serait alors d'obtenir des instances en lecture seule 'synthétiques' à partir de ces vues, ce qui devrait faciliter l'alimentation des données agrégées dans une interface utilisateur.

Modifier:

Il semble que je n'ai pas rendu le problème assez clair, alors voici ce que j'essaie de faire: je veux écrire du code indépendant de la base de données utilisée. Puisque j'utilise hibernate, je devrais juste changer le fichier de configuration du dialecte et pourrait ensuite utiliser un autre SGBD.

Question: comment créer Vues sur mes entités hibernate sans s'appuyer 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 a-t-il un plug-in hibernate supplémentaire pour m'aider avec cela? N'ai rien trouvé jusqu'à présent... :-/

25
demandé sur Roland Ewald 2009-05-23 17:28:15

4 réponses

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 sous-jacente. Fondamentalement, il prend en charge suffisamment de 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 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 mappage 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 que vous voulez en ajoutant plus de sections "database-object". Vous devez écrire le SQL (DDL) vous-même pour chaque base de données que vous souhaitez prendre en charge, mais comme elles sont étendues au dialecte, Hibernate n'exécutera que le SQL pour le dialecte choisi au moment de l'exportation du schéma.

22
répondu Rob H 2009-05-27 03:15:11

A eu le même problème et a trouvé la solution suivante dans la doucmentation hibernate:

Il N'y a pas de différence entre une vue et une table de base pour une hibernation cartographie. Ceci est transparent à la niveau de base de données, bien que certains SGBD ne supporte pas les vues correctement, en particulier avec les mises à jour. Parfois, vous voulez utilisez une vue, mais vous ne pouvez pas en créer une dans la base de données (c'est à dire avec un héritage schéma). Dans ce cas, vous pouvez mapper un immuable et en lecture seule à un l'expression de sous-sélection 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

12
répondu Dominik 2014-02-06 10:00:00

Que voulez-vous dire par "créer une vue"? Je sais ce que cela signifie d'un contexte de base de données pur-mais ce n'est pas ce que vous voulez dire - n'est-ce pas?

Vous pouvez mapper de nouvelles classes Java aux 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

0
répondu Tom 2009-05-26 18:20:33

Pouvez-vous déclarer les vues directement dans la base de données? Ensuite, vous pouvez simplement sélectionner directement à partir des vues. Jetez un oeil à Chapitre 10.4.4 du manuel Hibernate

Cela devrait vous permettre de sélectionner à partir de la vue de base de données et D'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
répondu Ben Hammond 2012-10-02 17:23:46