Будьте в спящем режиме не обновляет запись - Калитка

Я работаю над веб-приложением с Калиткой, Spring и В спящем режиме, и я столкнулся с проблемой с обновлением записей. Я проверил, что saveOrUpdate метод вызывается, и что данные в объекте области изменились. Произведенный SQL однако не отображает это, любые изменения в базе данных были внесены (ОБНОВЛЕНИЕ в примере), и затронутая запись не была обновлена.

Я предположил бы, что имеет больше смысла использовать обновление (), но я, saveOrUpdate () действительно удается создать новые записи, но это не обновляет их. Я проверил, что этот метод вызывается, и UserVO, который передается, действительно содержит обновленные поля. Вот метод ДАО:

public class SkuldwebDAOImpl extends HibernateDaoSupport implements SkuldwebDAO {
    public void updateUser(UserVO userVO) {
        getSession().saveOrUpdate(userVO);
    }
}

Вот мой файл свойств:

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

Вот sessionFactory боб в 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>

Надо надеяться, один из Вас может выручить меня.

Обновленный Здесь некоторая информация от журнала (onSubmit (), выделяет эти записи в журнале - последняя запись должна состоять в том, когда запрос перенаправляется к другой странице (после того, как запись должна была быть обновлена).


[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.request.target.component.listener.ListenerInterfaceRequestTarget@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=john@upbeat.no,userprofile__form2_hf_0=} onlyProcessIfPathActive=false]) with [BookmarkablePageRequestTarget@1030849724 pageClass=com.upbeat.app.skuldweb.web.user.UserProfilePage]

Обновите 2, Вот UserVO без методов считывания/методов set

@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;

}

10
задан skaffman 30 November 2010 в 20:59
поделиться

2 ответа

Hibernate часто откладывает обновления до сброса сеанса. Чтобы проверить, является ли это проблемой в вашем случае, вставьте getSession (). Flush () после оператора обновления.

Как вы управляете транзакциями? Сброс будет происходить автоматически, когда сеанс зафиксирован, но если у вас есть неправильная конфигурация транзакции, вы можете в конечном итоге зафиксировать соединение JDBC, но не зафиксировать транзакцию, привязанную к сеансу Hibernate.

Изменить: На основании вашего обновления я вижу, что FlushMode в какой-то строке установлен НИКОГДА:

[TRACE] 2010-07-23 00:29:26,303 :org.hibernate.impl.SessionImpl.setFlushMode(SessionImpl.java:1316): setting flush mode to: NEVER

Я подозреваю, что это проблема. Это приводит к тому, что сеанс никогда не сбрасывается автоматически - обычно это то, что вы хотите делать в транзакции только для чтения, а не при изменении данных. Похоже, вы работаете без транзакций (для autocommit установлено значение true, что, кстати, не рекомендуется). Документация Javadoc для OpenSessionInViewFilter дает некоторые подсказки:

Этот фильтр по умолчанию не сбрасывает сеанс Hibernate, при этом для режима очистки установлено значение FlushMode.NEVER. Предполагается, что он будет использоваться в сочетании с транзакциями уровня сервиса, которые заботятся о сбросе: активный диспетчер транзакций временно изменит режим сброса на FlushMode.AUTO во время транзакции чтения-записи, с сбросом режима сброса на FlushMode. НИКОГДА в конце каждой транзакции. Если вы собираетесь использовать этот фильтр без транзакций, рассмотрите возможность изменения режима очистки по умолчанию (с помощью свойства «flushMode»).

Другими словами, у вас есть два варианта: либо установить для flushMode в OpenSessionInViewFilter значение AUTO, либо отключить автоматическую фиксацию и настроить диспетчер транзакций, такой как HibernateTransactionManager .

26
ответ дан 3 December 2019 в 14:43
поделиться

Поскольку вы используете Spring, я бы рекомендовал вам использовать Spring PlatformTransactionManager для управления вашими транзакциями. В рамках управления транзакциями Spring автоматически очищает сеанс. Это означает, что вам не нужно беспокоиться ни об одном из этих аспектов вашего кода.

Spring имеет OpenSessionInViewFilter, который подключается к диспетчеру транзакций для запуска / очистки сеансов, и вы можете аннотировать свои методы с помощью Spring @Transactional, чтобы указать, что вам нужна транзакция «записи» для определенного метода. Это должно обновить ваши записи.

6
ответ дан 3 December 2019 в 14:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: