Hibernate n'est pas la mise à jour de l'enregistrement de Guichet
Je travaille sur une application web avec Portillon, Spring et Hibernate et j'ai rencontré un problème avec la mise à jour des enregistrements. J'ai vérifié que le saveOrUpdate méthode est appelée, et que les données dans le domaine de l'objet a changé. Le SQL de sortie n'a cependant pas afficher toutes les modifications apportées à la base de données a été faite (mise à JOUR par exemple) et l'enregistrement concerné n'a pas été mis à jour.
Je suppose qu'il est plus logique d'utiliser la mise à jour (), mais je saveOrUpdate() ne parviennent à créer de nouveaux dossiers, mais il n'a pas les mettre à jour. J'ai vérifié que cette méthode EST appelée, et les UserVO qui est passé en contient la mise à jour des champs. Voici la méthode DAO:
public class SkuldwebDAOImpl extends HibernateDaoSupport implements SkuldwebDAO {
public void updateUser(UserVO userVO) {
getSession().saveOrUpdate(userVO);
}
}
Voici mon fichier de propriétés:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/skuldweb_dev;AUTO=MULTI;CURSOR=READONLY
jdbc.username=
jdbc.password=
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.use_outer_join=true
hibernate.cache.use_query_cache=true
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider=org.hibernate.cache.HashtableCacheProvider
hibernate.schemaUpdate=true
Voici la sessionFactory haricot applicationContext.xml:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="use_outer_join">${hibernate.use_outer_join}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider}</prop>
<prop key="hibernate.connection.pool_size">10</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.jdbc.batch_size">1000</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.upbeat.app.skuldweb.domain.UserVO</value>
<value>com.upbeat.app.skuldweb.domain.UserLevelVO</value>
</list>
</property>
<property name="schemaUpdate" value="${hibernate.schemaUpdate}"/>
</bean>
Espérons que l'un de vous peut m'aider.
Mis à jour Voici quelques infos dans le journal (onSubmit() déclenche ces entrées dans le journal -- la dernière entrée doit être quand la demande est en train d'être redirigé vers une autre page (après l'enregistrement doit avoir été mis à jour).
[DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.lookupSessionFactory(OpenSessionInViewFilter.java:239): à l'Aide d'une SessionFactory 'sessionFactory" pour OpenSessionInViewFilter [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:214): le Retour de mise en cache de l'instance du singleton bean "sessionFactory' [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:181): Ouverture unique Session Hibernate dans OpenSessionInViewFilter [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:318): Ouverture de la Session Hibernate [DEBUG] 2010-07-23 00:29:26,303 :org.mise en veille prolongée.impl.SessionImpl.(SessionImpl.java:247): session ouvert à timestamp: 5242215490777088 [TRACE] 2010-07-23 00:29:26,303 :org.mise en veille prolongée.impl.SessionImpl.setFlushMode(SessionImpl.java:1316): réglage de rincer la mode: ne JAMAIS [DEBUG] 2010-07-23 00:29:26,305 :org.apache.wicket.Session.getPage(Session.java:700): mise en page [path = 4:userprofile_form, versionNumber = 0] [DEBUG] 2010-07-23 00:29:26,306 :org.apache.wicket.markup.html.form.persistence.CookieValuePersister.getCookie(CookieValuePersister.java:210): Impossible de trouver le Cookie name=userprofile_form.e-mail et l'URI de la demande=/optimiste-app-skuld-web/ [TRACE] 2010-07-23 00:29:26,308 :org.mise en veille prolongée.moteur.IdentifierValue.isUnsaved(IdentifierValue.java:127): id unsaved-value: 0 [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:546): instance détachée de: com.optimiste.app.skuldweb.domaine.UserVO [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:228): mise à jour instance détachée [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:295): mise à jour [com.optimiste.app.skuldweb.domaine.UserVO#1] [TRACE] 2010-07-23 00:29:26,310 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:346): mise à jour [com.optimiste.app.skuldweb.domaine.UserVO#1] [TRACE] 2010-07-23 00:29:26,311 :org.mise en veille prolongée.moteur.En Cascade.cascade(Cascade.java:138): traitement cascade ACTION_SAVE_UPDATE: com.optimiste.app.skuldweb.domaine.UserVO [TRACE] 2010-07-23 00:29:26,312 :org.mise en veille prolongée.moteur.CascadingAction$5.cascade(CascadingAction.java:239): cascade de saveOrUpdate: com.optimiste.app.skuldweb.domaine.UserLevelVO [TRACE] 2010-07-23 00:29:26,312 :org.mise en veille prolongée.moteur.IdentifierValue.isUnsaved(IdentifierValue.java:127): id unsaved-value: 0 [TRACE] 2010-07-23 00:29:26,312 :org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:546): instance détachée de: com.optimiste.app.skuldweb.domaine.UserLevelVO [TRACE] 2010-07-23 00:29:26,312 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:228): mise à jour instance détachée [TRACE] 2010-07-23 00:29:26,313 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:295): mise à jour [com.optimiste.app.skuldweb.domaine.UserLevelVO#1] [TRACE] 2010-07-23 00:29:26,313 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:346): mise à jour [com.optimiste.app.skuldweb.domaine.UserLevelVO#1] [TRACE] 2010-07-23 00:29:26,313 :org.mise en veille prolongée.moteur.En Cascade.cascade(Cascade.java:173): fait de traitement de la cascade ACTION_SAVE_UPDATE: com.optimiste.app.skuldweb.domaine.UserVO [DEBUG] 2010-07-23 00:29:26,314 :org.apache.wicket.RequestCycle.setRequestTarget(RequestCycle.java:644): remplacement de demande de cible org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget@676067951[Page class = com.optimiste.app.skuldweb.web.de l'utilisateur.UserProfilePage, id = 4, version = 0]->userprofile_form->interface org.apache.wicket.balisage.html.forme.IFormSubmitListener.IFormSubmitListener (demande de paramètres: [RequestParameters componentPath=4:userprofile_form pageMapName=null versionNumber=0 nom_interface=IFormSubmitListener componentId=null behaviorId=null urlDepth=-1 paramètres={[email protected],userprofile__form2_hf_0=} onlyProcessIfPathActive=faux]) avec [BookmarkablePageRequestTarget@1030849724 pageClass=com.optimiste.app.skuldweb.web.de l'utilisateur.UserProfilePage]
Mise à jour 2
Voici la UserVO sans les getters/setters
@Entity @Table(name = "USERS") @NamedQueries({ @NamedQuery(name = "user.getById", query = "from UserVO item where item.id = :id"), @NamedQuery(name = "user.getAllUsers", query = "from UserVO item order by item.registerDate desc"), @NamedQuery(name = "user.countAll", query = "select count(item) from UserVO item"), @NamedQuery(name = "user.getByUsername", query = "from UserVO item where item.username = :username"), @NamedQuery(name = "user.authenticate", query = "from UserVO item where item.username = :username AND item.passwordHash = :passwordHash") }) public class UserVO extends BaseVO {
@Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ID") protected long id; @OneToOne(cascade = CascadeType.ALL) protected UserLevelVO userLevelVO; @Basic @Column(name = "USERNAME") protected String username; @Basic @Column(name = "PASSWORD_HASH") protected String passwordHash; @Basic @Column(name = "EMAIL") protected String email; @Temporal(TemporalType.TIMESTAMP) @Column(name = "REGISTER_DATE") protected Date registerDate; @Temporal(TemporalType.TIMESTAMP) @Column(name = "LAST_LOGIN_DATE") protected Date lastLoginDate;
}
OriginalL'auteur John | 2010-07-22
Vous devez vous connecter pour publier un commentaire.
Hibernate souvent reporte les mises à jour jusqu'à ce que la session est vidé. Pour tester si c'est le problème dans votre cas, insérez une
getSession().flush()
après votre mise à jour de la déclaration.Comment faites-vous pour gérer les transactions? Le rinçage se fera automatiquement lorsque la session s'est engagé, mais si vous avez une mauvaise configuration de la transaction, vous risquez de commettre de la connexion JDBC, mais pas la validation de la transaction liée à la session Hibernate.
Edit: Basé sur votre mise à jour, je vois que FlushMode est fixé à JAMAIS à un certain nombre de lignes:
Je suppose que c'est le problème. Il provoque la session ne jamais rincer automatiquement - ce qui est généralement ce que vous voulez faire en lecture seule transaction, pas lorsque vous modifiez les données. Il semble que vous êtes en cours d'exécution sans transactions (autocommit défini à true, ce qui n'est pas recommandé par la voie). La Javadoc de OpenSessionInViewFilter fournit quelques indices:
En d'autres termes, vous avez deux options: soit définir
flushMode
sur votre OpenSessionInViewFilter AUTO, ou, désactiver la validation automatique et configurer un gestionnaire de transactions telles que HibernateTransactionManager.Merci beaucoup! L'ajout de getSession().flush() la méthode de mise à jour a fait un travail. Je l'ai fait essayer le réglage de flushMode sur "AUTO" dans le OpenSessionInViewFilter, mais j'ai toujours eu à appeler manuellement getSession().flush() pour exécuter la mise à jour (avec autocommitt sur et en dehors).
Avec flushMode réglé sur AUTO et avoir désactivé en mode autocommit, j'ai été capable de le faire fonctionner en faisant Transaction tr = getSession().beginTransaction(); getSession().mise à jour(vo); tr.commit();. Merci encore
OriginalL'auteur waxwing
Puisque vous êtes vous à l'aide de Printemps, je vous recommande d'utiliser le Printemps PlatformTransactionManager pour gérer vos transactions. Dans le cadre de la gestion des transactions de Printemps, vide automatiquement la session. Cela signifie que vous n'avez pas à vous soucier de tous ces aspects dans votre code.
Printemps a un OpenSessionInViewFilter qui se raccorde à la transaction manager pour démarrer/chasse des sessions et vous pouvez annoter vos méthodes avec le Printemps @Transactionnelle pour indiquer que vous voulez une "écriture" de la transaction pour une méthode particulière. Cela devrait mettre à jour vos dossiers.
OriginalL'auteur Vineeth