Sto lavorando a un'applicazione web con Wicket, Spring e Hibernate e ho riscontrato un problema con l'aggiornamento dei record. Ho verificato che il metodo saveOrUpdate è stato richiamato e che i dati nell'oggetto dominio sono stati modificati. L'output SQL tuttavia non mostra che sono state apportate modifiche al database (UPDATE nell'esempio) e il record interessato non è stato aggiornato.Hibernate non sta aggiornando il record - Wicket
Direi che ha più senso usare update() ma I saveOrUpdate() riesce a creare nuovi record, ma non li aggiorna. Ho verificato che questo metodo sia stato richiamato e che l'utenteVO passato contenga i campi aggiornati. Ecco il metodo DAO:
public class SkuldwebDAOImpl extends HibernateDaoSupport implements SkuldwebDAO {
public void updateUser(UserVO userVO) {
getSession().saveOrUpdate(userVO);
}
}
Ecco il mio file di proprietà:
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
Ecco il fagiolo sessionFactory in 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>
Hopefully one of you can help me out.
Updated Here's some info from the log (onSubmit() sets off these entries in the log -- the last entry should be when the request is being redirected to another page (after the record should have been updated).
[DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.lookupSessionFactory(OpenSessionInViewFilter.java:239): Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:214): Returning cached instance of singleton bean 'sessionFactory' [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:181): Opening single Hibernate Session in OpenSessionInViewFilter [DEBUG] 2010-07-23 00:29:26,302 :org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:318): Opening Hibernate Session [DEBUG] 2010-07-23 00:29:26,303 :org.hibernate.impl.SessionImpl.(SessionImpl.java:247): opened session at timestamp: 5242215490777088 [TRACE] 2010-07-23 00:29:26,303 :org.hibernate.impl.SessionImpl.setFlushMode(SessionImpl.java:1316): setting flush mode to: NEVER [DEBUG] 2010-07-23 00:29:26,305 :org.apache.wicket.Session.getPage(Session.java:700): Getting 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): Unable to find Cookie with name=userprofile_form.email and request URI=/upbeat-app-skuld-web/ [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.engine.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): detached instance of: com.upbeat.app.skuldweb.domain.UserVO [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:228): updating detached instance [TRACE] 2010-07-23 00:29:26,308 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:295): updating [com.upbeat.app.skuldweb.domain.UserVO#1] [TRACE] 2010-07-23 00:29:26,310 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:346): updating [com.upbeat.app.skuldweb.domain.UserVO#1] [TRACE] 2010-07-23 00:29:26,311 :org.hibernate.engine.Cascade.cascade(Cascade.java:138): processing cascade ACTION_SAVE_UPDATE for: com.upbeat.app.skuldweb.domain.UserVO [TRACE] 2010-07-23 00:29:26,312 :org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:239): cascading to saveOrUpdate: com.upbeat.app.skuldweb.domain.UserLevelVO [TRACE] 2010-07-23 00:29:26,312 :org.hibernate.engine.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): detached instance of: com.upbeat.app.skuldweb.domain.UserLevelVO [TRACE] 2010-07-23 00:29:26,312 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:228): updating detached instance [TRACE] 2010-07-23 00:29:26,313 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:295): updating [com.upbeat.app.skuldweb.domain.UserLevelVO#1] [TRACE] 2010-07-23 00:29:26,313 :org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:346): updating [com.upbeat.app.skuldweb.domain.UserLevelVO#1] [TRACE] 2010-07-23 00:29:26,313 :org.hibernate.engine.Cascade.cascade(Cascade.java:173): done processing cascade ACTION_SAVE_UPDATE for: com.upbeat.app.skuldweb.domain.UserVO [DEBUG] 2010-07-23 00:29:26,314 :org.apache.wicket.RequestCycle.setRequestTarget(RequestCycle.java:644): replacing request target org.apache.wicket.r[email protected]676067951[Page class = com.upbeat.app.skuldweb.web.user.UserProfilePage, id = 4, version = 0]->userprofile_form->interface org.apache.wicket.markup.html.form.IFormSubmitListener.IFormSubmitListener (request paramaters: [RequestParameters componentPath=4:userprofile_form pageMapName=null versionNumber=0 interfaceName=IFormSubmitListener componentId=null behaviorId=null urlDepth=-1 parameters={[email protected],userprofile__form2_hf_0=} onlyProcessIfPathActive=false]) with [[email protected] pageClass=com.upbeat.app.skuldweb.web.user.UserProfilePage]
Update 2 Here's the UserVO without the 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;
}
Sì, buona cattura +1 –
Grazie mille! L'aggiunta di getSession(). Flush() al metodo di aggiornamento ha funzionato. Ho provato a impostare flushMode su "AUTO" in OpenSessionInViewFilter, ma dovevo comunque richiamare manualmente getSession(). Flush() per eseguire l'aggiornamento (con autocommitt on e off). – John
Con flushMode impostato su AUTO e disabilitando l'autocommit, sono riuscito a farlo funzionare; Transaction tr = getSession(). BeginTransaction(); getSession aggiornamento() (vo).; tr.commit() ;. Grazie ancora – John