probleme update org.hibernate.TransientObjectException
Bonjour.
J'ai un problème lors de la mise à jour d'un objet via Hibernate suite à la saisie dans un formulaire.
Je pense avoir vu comment résoudre le problème, mais je voulais savoir si c'était la bonne méthode.
Voici l'erreur :
Code:
1 2 3
| 2014-03-13 10:34:43,659 DEBUG cpte.dao.CpteLieuDao - update(T) : cpte.hibernate.CpteLieu
Hibernate: update CPTEADM.CPTE_LIEU set LIE_ID_PARENT=?, LIE_LIBELLE=?, LIE_CODE=?, LIE_CENTRE_PROFIT=?, LIE_NIVEAU=? where LIE_ID=?
2014-03-13 10:34:52,167 ERROR cpte.pages.admin.lieu.PageLieuAction - org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cpte.hibernate.CpteLieu |
Voici le mapping d'un lieu.
Note : Un lieu peut avoir un lieu supérieur (ou pas si c'est le niveau maximum)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
<hibernate-mapping>
<class name="cpte.hibernate.CpteLieu" table="CPTE_LIEU">
<id name="lieId" type="long">
<column name="LIE_ID" precision="22" scale="0" />
<generator class="increment" />
</id>
<many-to-one name="cpteLieuParent" class="cpte.hibernate.CpteLieu" fetch="select">
<column name="LIE_ID_PARENT" precision="22" scale="0" />
</many-to-one>
<property name="lieLibelle" type="string">
<column name="LIE_LIBELLE" length="80" />
</property>
...
<set name="cpteLieux" table="CPTE_LIEU" order-by="LIE_ID" inverse="true" lazy="true" fetch="select">
<key>
<column name="LIE_ID_PARENT" precision="22" scale="0" />
</key>
<one-to-many class="cpte.hibernate.CpteLieu" />
</set>
</class>
</hibernate-mapping> |
La modification fonctionne correctement lorsque qu'il y a un lieu parent mais pas lorsqu'il n'y en a pas.
Dans le java, avant d'arriver sur le formulaire, le lieu contient les paramètre suivants : "cpteLieuParent=null"
J'arrive donc sur mon formulaire jsp de modification :
Code:
1 2 3 4 5 6
|
<s:form name="lieuForm">
<s:textfield name="lieu.lieId" readonly="true" label="%{getText('label.lieu.lieId')}" />
<s:textfield name="lieu.lieLibelle" required="true" label="%{getText('label.lieu.lieLibelle')}" />
....
<s:textfield name="lieu.cpteLieuParent.lieId" label="%{getText('label.lieu.lieIdParent')}" /> |
--> l'input correspondant au champ lieu.cpteLieuParent.lieId n'est pas renseigné.
Lors de la validation du formulaire, j'arrive donc dans le java, qui considère que le champ cpteLieuParent est non null et contient un id cpteLieuParent.lieId=0.
Lors de la mise à jour :
Code:
1 2 3 4
|
HibernateUtil.currentSession().beginTransaction();
CpteLieuDao.getInstance().update(lieu);
HibernateUtil.currentSession().getTransaction().commit(); |
J'ai donc l'erreur lors du commit :
Code:
1 2
| Hibernate: update CPTEADM.CPTE_LIEU set LIE_ID_PARENT=?, LIE_LIBELLE=?, LIE_CODE=?, LIE_CENTRE_PROFIT=?, LIE_NIVEAU=? where LIE_ID=?
2014-03-13 10:34:52,167 ERROR cpte.pages.admin.lieu.PageLieuAction - org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cpte.hibernate.CpteLieu |
Pour cela vient du fait que le commit ne fonctionne pas car en base de donnée, il n'y a pas de lieu avec l'id=0.
Faut-il donc avant la mise à jour rajouter le code suivant :
Code:
1 2
| if(lieu.getCpteLieuParent() != null and lieu.getCpteLieuParent().getLieId==0)
setCpteLieuParent=null |
ou y-a-t-il autre chose de plus propre? en jsp ou en "hibernate"
Cordialement