Bonjour et merci pour ces réponses aussi rapides.
Alors effectivement je viens de constater que dans le DTD tout est correct, effectivement. Je ne sais pas pourquoi, mais il me semblait que seuls les index étaient autorisés dans les maps. Quoiqu'il en soit, voici mes classes :
AnnotationStateCode:
package eserve;
import eserve.bom.pojo.AbstractPOJOInstance;
public class AnnotationState extends AbstractPOJOInstance {
static final long serialVersionUID = -26057400L;
private java.lang.String id;
private java.lang.String iso_language_code;
private java.lang.String ml_id;
private java.lang.String title;
public AnnotationState(){}
public java.lang.String getId() {
return id;
}
public void setId(java.lang.String id){
this.id = id;
}
public java.lang.String getIso_language_code() {
return iso_language_code;
}
public void setIso_language_code(java.lang.String iso_language_code){
this.iso_language_code = iso_language_code;
}
public java.lang.String getMl_id() {
return ml_id;
}
public void setMl_id(java.lang.String ml_id){
this.ml_id = ml_id;
}
public java.lang.String getTitle() {
return title;
}
public void setTitle(java.lang.String title){
this.title = title;
}
public String getInstanceKeyString() {
return id == null ? null : id.toString();
}
public int hashCode() {
return id == null ? -421 : id.hashCode();
}
public boolean equals(Object object) {
if(object instanceof AnnotationState) {
return id != null && id.equals(((AnnotationState)object).id);
}
return false;
}
}
AnnotationStateMLCode:
package eserve;
import eserve.bom.pojo.AbstractPOJOInstance;
public class AnnotationStateML extends AbstractPOJOInstance {
static final long serialVersionUID = -2006079L;
private java.lang.String annotation;
private java.lang.String endActivityDesc;
private java.lang.String flowModelID;
private java.lang.String id;
private java.util.Map name = new java.util.HashMap();
private java.lang.String startActivityDesc;
public AnnotationStateML(){}
public java.lang.String getAnnotation() {
return annotation;
}
public void setAnnotation(java.lang.String annotation){
this.annotation = annotation;
}
public java.lang.String getEndActivityDesc() {
return endActivityDesc;
}
public void setEndActivityDesc(java.lang.String endActivityDesc){
this.endActivityDesc = endActivityDesc;
}
public java.lang.String getFlowModelID() {
return flowModelID;
}
public void setFlowModelID(java.lang.String flowModelID){
this.flowModelID = flowModelID;
}
public java.lang.String getId() {
return id;
}
public void setId(java.lang.String id){
this.id = id;
}
public java.util.Map getName() {
return name;
}
public void setName(java.util.Map name){
this.name = name;
}
public java.lang.String getStartActivityDesc() {
return startActivityDesc;
}
public void setStartActivityDesc(java.lang.String startActivityDesc){
this.startActivityDesc = startActivityDesc;
}
public String getInstanceKeyString() {
return id == null ? null : id.toString();
}
public int hashCode() {
return id == null ? -421 : id.hashCode();
}
public boolean equals(Object object) {
if(object instanceof AnnotationStateML) {
return id != null && id.equals(((AnnotationStateML)object).id);
}
return false;
}
}
Ce sont des classes générées, mais je ne pense pas que ça pose problème. J'ai rempli le fichier de conf. de hibernate de la manière standard, je pense :
hibernate.cfg.xmlCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--Database connection settings-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/ess_competence</property>
<property name="connection.username">root</property>
<property name="connection.password"/>
<property name="connection.pool_size">10</property>
<!--SQL dialect-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--Echo all executed SQL to stdout-->
<property name="show_sql">true</property>
<!--Mappings to load for each defined class-->
<mapping resource="AnnotationState.hbm.xml"/>
<mapping resource="AnnotationStateML.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Et les deux fichiers de conf pour les classes sont les suivants :
AnnotationState.hbm.xmlCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="eserve">
<class name="AnnotationState" table="ANNOTATION_STATE_ML_CONT">
<id name="id">
<generator class="assigned"/>
</id>
<property name="iso_language_code"/>
<many-to-one name="ml_id" class="AnnotationStateML" not-null="true"/>
<property name="title"/>
</class>
</hibernate-mapping>
AnnotationStateMLCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="eserve">
<class name="AnnotationStateML" table="ANNOTATION_STATE">
<id name="id">
<generator class="assigned"/>
</id>
<property name="annotation"/>
<property name="endActivityDesc" column="end_activity_desc"/>
<property name="flowModelID" column="flow_model_id"/>
<property name="startActivityDesc" column="start_activity_desc"/>
<map name="name" inverse="true" cascade="all-delete-orphan">
<key column="ML_ID"/>
<!--<map-key column="ISO_LANGUAGE_CODE"/>-->
<index column="ISO_LANGUAGE_CODE" type="string"/>
<one-to-many class="AnnotationState"/>
</map>
</class>
</hibernate-mapping>
Bon on pourrait croire qu'il y a un problème avec les noms des tables, mais ce n'est pas le cas : les noms ont été interverti pour je ne sais quelle raison et maintenant on ne peux plus le changer :/ (base en production)
Le véritable problème, c'est que je ne parviens pas à persister l'objet AnnotationStateML comme je le souhaiterais. En effet, le code que j'aimerais exécuter est le suivant :
Code:
BOMClassManager iface = bomRepository.getBOMClassManager();
// Test of the map : insert values to a map.
InstanceIntf instanceFR = iface.getClassIntf("AnnotationState").createInstance();
InstanceIntf instanceDE = iface.getClassIntf("AnnotationState").createInstance();
instanceFR.setAttrValue("title","version francaise");
instanceFR.setAttrValue("iso_language_code","FR");
instanceDE.setAttrValue("title","deutsche version");
instanceDE.setAttrValue("iso_language_code","DE");
// Test of the map : connect the preceding values to the map.
InstanceIntf instanceMap = iface.getClassIntf("AnnotationStateML").createInstance();
instanceMap.setAttrValue("annotation","this the first map handled by hibernate");
instanceMap.setAttrValue("endActivityDesc","END");
instanceMap.setAttrValue("flowModelID","no idea ;)");
instanceMap.setAttrValue("startActivityDesc","BEGIN");
Map map = (Map)instanceMap.getAttrValue("name");
map.put("FR",instanceFR);
map.put("DE",instanceDE);
instanceMap.setAttrValue("name",map);
Session s = this.hibernateRepository.currentSession();
Transaction tx = s.beginTransaction();
s.save(instanceMap);
tx.commit();
Je ne vais pas rentrer dans le détail mais en gros, BOMClassManager est une factory d'objets, et InstanceIntf est une instance d'une classe d'un certain type. Tout ceci fonctionnait avant hibernate, donc je ne pense pas que le problème vienne de là. Ce qui se passe, c'est que lorsque je fais le commit, j'obtiens l'erreur suivante :
Code:
org.hibernate.PropertyValueException: not-null property references a null or transient value: eserve.AnnotationState.ml_id
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:164)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:190)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:70)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at eserve.components.hibernate.HibernateComponent.doStart(HibernateComponent.java:107)
...
Il semblerait donc qu'hibernate ne remplisse pas le champ ml_id automatiquement. Je pense que mes fichiers de mapping ne sont pas corrects mais je ne vois pas trop où (ce qui m'aiderai beaucoup serait déjà de savoir s'ils sont corrects et adaptés à ce que je veux faire). Si j'enlève la clause not-null, Hibernate tente de faire un update sur les objets instanceFR et instanceDE au lieu de les insérer dans la base.
Voilà, j'ai mis à peu près tout ce dont je dispose. Désolé pour la taille de ce message abominablement grand, mais j'ai préféré tout mettre pour que ce soit plus "clair" ;)
A bientôt,
Joël.