Comment puis-je cartographier "insert='false' update='false'" sur une propriété composite-id key-qui est également utilisée dans un FK "one-to-many"?
je travaille sur une base de code legacy avec un schéma DB existant. Le code existant utilise SQL et PL/SQL pour exécuter des requêtes sur la base de données. Nous avons été chargés de faire une petite partie de la base de données de projet-moteur agnostic (au début, tout changer éventuellement). Nous avons choisi d'utiliser hibernation 3.3.2.GA et"*.hbm.fichiers de mappage xml" (par opposition aux annotations). Malheureusement, il n'est pas possible de modifier le schéma existant, parce que nous ne pouvons pas retourner les l'héritage de fonctionnalités.
le problème que je rencontre est quand je tente de cartographier une relation unidirectionnelle, un-à-plusieurs où le FK est aussi partie d'un composite PK. Voici les classes et le fichier de mappage...
CompanyEntity.java
public class CompanyEntity {
private Integer id;
private Set<CompanyNameEntity> names;
...
}
CompanyNameEntity.java
public class CompanyNameEntity implements Serializable {
private Integer id;
private String languageId;
private String name;
...
}
CompanyNameEntity.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example">
<class name="com.example.CompanyEntity" table="COMPANY">
<id name="id" column="COMPANY_ID"/>
<set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false">
<key column="COMPANY_ID"/>
<one-to-many entity-name="vendorName"/>
</set>
</class>
<class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME">
<composite-id>
<key-property name="id" column="COMPANY_ID"/>
<key-property name="languageId" column="LANGUAGE_ID"/>
</composite-id>
<property name="name" column="NAME" length="255"/>
</class>
</hibernate-mapping>
ce code fonctionne juste amende pour le choix et L'insertion d'une société avec des noms. J'ai rencontré un problème lorsque j'ai essayé de mettre à jour et enregistrement existant. J'ai reçu une BatchUpdateException et après avoir regardé à travers les logs SQL j'ai vu Hibernate essayait de faire quelque chose stupide ...
update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=?
Hibernate essayait de dissocier les dossiers des enfants avant de les mettre à jour. Le problème est que ce champ fait partie du PK et n'est pas nul. J'ai trouvé la solution rapide à faire Hibernation ne pas faire ceci est d'ajouter "not-null= 'true' "à l'élément" key " dans le mappage parent. ALORS maintenant, peut-cartographie ressemble à ceci...
CompanyNameEntity.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example">
<class name="com.example.CompanyEntity" table="COMPANY">
<id name="id" column="COMPANY_ID"/>
<set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false">
<key column="COMPANY_ID" not-null="true"/>
<one-to-many entity-name="vendorName"/>
</set>
</class>
<class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME">
<composite-id>
<key-property name="id" column="COMPANY_ID"/>
<key-property name="languageId" column="LANGUAGE_ID"/>
</composite-id>
<property name="name" column="NAME" length="255"/>
</class>
</hibernate-mapping>
Cette cartographie donne l'exception...
org.hibernate.MappingException: Repeated column in mapping for entity: companyName column: COMPANY_ID (should be mapped with insert="false" update="false")
mon problème maintenant est que j'ai essayé d'ajouter ces attributs à l'élément clé-propriété mais cela n'est pas supporté par la DTD. J'ai également essayé de le transformer en un élément clé-plusieurs-en-un, mais ne fonctionne pas non plus. Si...
Comment puis-je carte "insert=" false "update=" false "" sur un composite-id-clés de la propriété qui est également utilisé dans un un-à-plusieurs FK?
2 réponses
je pense que l'annotation que vous recherchez est:
public class CompanyName implements Serializable {
//...
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "COMPANY_ID", insertable = false, updatable = false)
private Company company;
et vous devriez pouvoir utiliser des mappages similaires dans un hbm.xml comme indiqué ici (en 23.4.2):
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-mappings.html
"Dino TW" a fourni le lien vers le commentaire Hibernate Mapping Exception : la répétition d'une colonne dans la cartographie pour l'entité qui est l'essentiel de l'information.
le lien suggère de fournir" inverse=true " dans le jeu de mapping, Je l'ai essayé et il fonctionne réellement. C'est une situation si rare où un ensemble et une clé Composite se rejoignent. Faire inverse=true, nous laissons l'insertion et la mise à jour de la table avec la clé Composite pour être pris en charge par lui-même.
ci-dessous peut être la cartographie requise,
<class name="com.example.CompanyEntity" table="COMPANY">
<id name="id" column="COMPANY_ID"/>
<set name="names" inverse="true" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false">
<key column="COMPANY_ID" not-null="true"/>
<one-to-many entity-name="vendorName"/>
</set>
</class>