Hibernate héritage et de plusieurs tables avec la même classe
Je suis assez nouveau à Hibernate. Dans ma situation, j'ai une table concret avec des enregistrements contenant rejoindre Id pour une multitude d'autres tableaux de la même structure.
Ce que j'aimerais accomplir est d'obtenir quelque chose comme
SELECT *
FROM main_records mr, ref1 r1, ref2 r2
WHERE r1.id = mr.id_ref1
AND r2.id = mr.id_ref2;
L'idée principale serait de réutiliser la classe pour toutes les références à des jointures.
SQL
CREATE TABLE main_records
(
id integer NOT NULL,
id_ref1 integer NOT NULL,
id_ref2 integer NOT NULL
)
CREATE TABLE ref1
(
id integer NOT NULL,
value character varying
)
CREATE TABLE ref2
(
id integer NOT NULL,
value character varying
)
J'ai configuré la base des classes POJO
Classes JAVA
public class MainRecord {
private Integer id;
private Ref ref1;
private Ref ref2;
...
//getters and setters
}
public class Ref {
private Integer id;
private String value;
...
//getters and setters
}
Mon idée est de définir les Hibernate mappages dans la manière suivante:
Définir un résumé super classe
<hibernate-mapping package="test">
<class abstract="true" name="Ref">
<id name="id" type="java.lang.Integer" column="ID">
<generator class="native" />
</id>
<property name="value" type="java.lang.String" column="VALUE" />
</class>
</hibernate-mapping>
La carte principale de l'entité d'étendre la super classe, mais de l'utilisation des tables de
<hibernate-mapping package="test">
<union-subclass name="Ref1" table="REF1" extends="Ref" />
<union-subclass name="Ref2" table="REF2" extends="Ref" />
<class name="MainRecord" table="MAIN_RECORDS">
<id name="id" column="ID" type="java.lang.Integer" />
<many-to-one name="ref1" class="Ref1" column="ID_REF1" fetch="join" unique="true" />
<many-to-one name="ref2" class="Ref2" column="ID_REF2" fetch="join" unique="true" />
</union-subclass>
</class>
</hibernate-mapping>
Je le fais manuellement inclure des fichiers de mappage dans la configuration, le chargement semble ok, mais ensuite, une erreur se produit, sans aucune detaild explication:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.transport.servlet.ServletTransportFactory' defined in class path resource [META-INF/cxf/cxf-servlet.xml]: Error setting property values;
nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (2) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'bus' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/database.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
PropertyAccessException 2: org.springframework.beans.MethodInvocationException: Property 'transportIds' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/spring/database.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1361)
Le système est un mélange de Spring 2.5, Hibernate 3.2, Cxf 2.3.4, Javassist 3.11,
Mes questions sont:
(un) Est-ce la bonne démarche?
(b) L'erreur se produit dès que j'ai introduire
<union-subclass name="Ref1" table="REF1" extends="Ref" />
<union-subclass name="Ref2" table="REF2" extends="Ref" />
donc je suppose que ce n'est pas la meilleure façon de le faire?
(c) Peut être écrit avec des annotations? Je ne peux pas imaginer comment définir le Ref1 et Ref2 classes sans pour autant créer une classe POJO pour eux.
(d) je Peux l'utilisateur plus de 1 niveau de l'héritage? J'aimerais, par exemple, l'utilisation d'un résumé de la superclasse de toutes mes tables en béton, qui couvrent l'audit des champs qu'ils ont tous en commun?
Disons classe Réf s'étend un résumé AuditTable classe, à la fois en Java Hibernate et des mappages.
OriginalL'auteur Andraz | 2011-07-29
Vous devez vous connecter pour publier un commentaire.
Si je comprends correctement à la question, Vous avez une fiche de table avec plusieurs clé étrangère à beaucoup de table qui ont les mêmes colonnes les unes des autres ?
Pas, Vous essayez de faire de l'héritage par l'aide de la Table par classe de la stratégie de sorcière, je pense, n'est pas approprié d'utiliser ici parce que vous avez une référence pour chaque pour chaque type d'objet(champ Ref1 et champ Ref2 dans votre cas).
Le cas d'utilisation qui peut être approprié d'utiliser l'héritage est si vous en avez un polymorphe de l'association de Ref dans le MasterRecord objet
Exemple des polymorphes de l'association de Ref
L'association
anyObjectRef1OrRef2
aurait été de la carte avec le<any ... />
élément dans la cartographie de MasterRecord. Il aurait besoin de deux une colonne avec le nom de classe et un pour le foreignKeyCe que vous devez faire est d'hériter des propriétés d'une super-classe (pas de table spécifique pour cette super-classe)
Oui utiliser @MappedSuperclass annotation.
Hibernate Implémentation de référence (à l'Aide de l'Annotation)
Il ne peut pas se faire sans la création d'Ref1 et Ref2 classes pojo.
Exemple avec l'annotation
De La Classe De Base Ref.java
Classe Ref1.java
Classe Ref2.java
Classe MainRecord.java
De créer et d'enregistrer l'entité en suivre
à utiliser hibernate mappage de fichier, vous devez supprimer toutes les annotations utilisation de la cartographie ci-dessous.
Pas que lors de l'utilisation d'un fichier de mappage, le résumé
Ref.java
super-classe n'est pas mappé et toutes les propriétés de la super-classe est à chaque enfant de mappage de fichier.OriginalL'auteur Joel Hudon
Juste une question.... si vous utilisez la même classe d'accéder à plusieurs tables différentes...
À la table dans laquelle seront stockés les nouvelles instances que vous enregistrez? Comment Hibernate savoir?
Autant que je sache, ce ne peut pas être fait.
OriginalL'auteur SJuan76
Raccourcis comme ceux-ci, même si elles peuvent être faites à travailler, souvent conduire sur une route de l'éventuelle confusion pour les développeurs qui héritent de votre code. Avant de poser la question "peut-il être fait", demander: "faut-il le faire".
Pense bas de la route: est-il préférable d'être plus "efficace" au temps de développement par la création de moins de classes et à l'aide d'une un peu obscure fonction, ou est-il mieux de faire juste les catégories distinctes et rendre les choses plus compréhensibles. Aussi, vous pouvez cocher vous-même dans un coin parce que cette particularité peut avoir des conséquences inattendues, le classique "pourquoi est-il en train de faire que" de la situation.
J'ai hérité de nombreuses applications où les précédentes générations de développeurs voulaient faire quelque chose de "cool" ou "élégante" les moyens et finit par causer plus de confusion que s'ils avaient gardé les choses concrètes et simples.
Il suffit de créer une classe séparée.
OriginalL'auteur atrain