关于hibernate的save方法无效的问题

J2EE 码拜 6年前 (2015-04-08) 1305次浏览 0个评论
 

【100分】请教关于hibernate的save方法无效的问题

1、serviceImpl方法如下:

@Repository
public class VersionControlServiceImpl  extends BaseHibernateDAO<Versioncontrol, String> implements VersionControlService{

	private Logger log = Logger.getLogger(VersionControlServiceImpl.class);


	@Override
	public void saveOrUpDate(Versioncontrol versionControl) {
		log.debug("saving Userinfo instance");
		try {
			Session session = this.getSession();

			super.saveOrUpDate(versionControl);
//			this.getSession().save(versionControl);
//			this.getSession().flush();
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

}

代码如上所示,如果用super.saveOrUpDate(versionControl); 这个方法来保存的话,根本值就没存进数据库,感觉像是事物没开启一样。
但是,用下面的两行
// this.getSession().save(versionControl);
// this.getSession().flush();

就是这注释掉的两行,则是可以存进数据库的。起关键作用的是this.getSession().flush(); 这个flush方法,如果不加这个方法,也是存不进数据库的。

2、BaseHibernateDAO如下:

package com.example.basedao;

import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.example.util.GenericsUtils;

public class BaseHibernateDAO<E extends java.io.Serializable, PK extends java.io.Serializable>
		implements IBaseHibernateDAO<E, PK> {
	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;


	private Class<E> entityClass;


	@SuppressWarnings("unchecked")
	public BaseHibernateDAO() {

		this.entityClass = GenericsUtils.getSuperClassGenricType(getClass());
	}

	public void delete(PK id) {
		getSession().delete(this.get(id));
		getSession().flush();
	}

	@SuppressWarnings("unchecked")
	public E get(PK id) {

		return (E) getSession().get(entityClass, id);
	}

	public Session getSession() {

		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	public List<E> listAll(){

		return getSession().createQuery("from "+entityClass.getName()).list();
	}

	public void save(E entity) {

		getSession().save(entity);

	}

	public void update(E entity) {

		getSession().update(entity);
		getSession().flush();
	}

	public void saveOrUpDate(E entity) {

		getSession().saveOrUpdate(entity);

	}

}

3、Spring关于事务的配置文件如下:

<!-- 配置文件 数据库配置文件或其他配置文件 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
                <value>classpath:config.properties</value>
            </list>
        </property>
    </bean>

	<!-- 数据库连接池配置 -->
  	<bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
		<property name="alias" value="proxoolDataSource"/>
		<property name="driver" value="${connection.driver_class}" />
		<property name="driverUrl" value="${connection.url}" />
		<property name="user" value="${connection.username}" />
		<property name="password" value="${connection.password}" />
		<property name="maximumConnectionCount" value="${proxool.maximum.connection.count}"/>
		<property name="minimumConnectionCount" value="${proxool.minimum.connection.count}" />
		<property name="statistics" value="${proxool.statistics}" />
		<property name="simultaneousBuildThrottle" value="${proxool.simultaneous.build.throttle}"/>
	</bean>

	<!-- SessionFactory配置 -->
  	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
    	<property name="dataSource" ref="dataSource"/>
    	<property name="packagesToScan">
			<list>
				<value>com.example.*</value>
			</list>
		</property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
                <prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>
                <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop>
                
                <!-- 缓存Cache配置 -->
                <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</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.region.factory_class">${hibernate.cache.region.factory_class}</prop>
                <prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</prop>
                <prop key="hibernate.cache.use_structured_entries">${hibernate.cache.use_structured_entries}</prop>
            </props>
        </property>
  	</bean>

	<!-- 开启AOP监听 只对当前配置文件有效 -->
	<aop:aspectj-autoproxy expose-proxy="true"/>

	<!-- 开启注解事务 只对当前配置文件有效 -->
  	<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>  

	<!-- 事务处理 -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

	<!-- 事物传播属性配置 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="merge*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="remove*" propagation="REQUIRED" />
            <tx:method name="put*" propagation="REQUIRED" />
            <tx:method name="use*" propagation="REQUIRED"/>
            <tx:method name="sessionDestroyed*" propagation="REQUIRED"/>
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="count*" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <tx:method name="list*" propagation="REQUIRED" read-only="true" />
            <tx:method name="*"  propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

	<!-- 事务拦截配置 -->
    <aop:config expose-proxy="true" >
        <aop:pointcut id="txPointcut" expression="execution(* com.example..*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>

4、让我奇怪的是,我另外一个实体这样保存是可以的,
而且不需要flush方法也是可以保存进数据库的。

另外一个实体与这个实体唯一不同的是,那个实体,主键是(id),Integer类型,而这个实体则是String(versionSequence),类型,(存放uuid类型)

关于hibernate的save方法无效的问题
5分
看后台打印sql
目测应该是执行了update了
关于hibernate的save方法无效的问题
引用 1 楼 EverWHL 的回复:

看后台打印sql
目测应该是执行了update了

后台啥都木有打印啊。

关于hibernate的save方法无效的问题
引用 2 楼 Javainging 的回复:
Quote: 引用 1 楼 EverWHL 的回复:

看后台打印sql
目测应该是执行了update了

后台啥都木有打印啊。

我写save() 咋会执行uodate()方法呢

关于hibernate的save方法无效的问题
5分
saveOrUpdate(单主键情况)
楼主你看看这个就明白了
一般来说如果你能确定你即将操作对象的状态,则不需要用saveOrUpdate
关于hibernate的save方法无效的问题
5分
我我可以把我的经验跟你讲一下,哈,经验如下:
如果如果实体的主键已经注解为自动生成,那么这个时候你在save之前再去设置这个主键,那么保存就会失败,如果需要主动设置,则把实体里自动生成主键的注解去掉。
关于hibernate的save方法无效的问题
引用 4 楼 EverWHL 的回复:

saveOrUpdate(单主键情况)
楼主你看看这个就明白了
一般来说如果你能确定你即将操作对象的状态,则不需要用saveOrUpdate

谢谢,我换成save()方法也是无效啊。这个不是单主键的问题啊、

让我奇怪的是,我另外一个实体这样保存是可以的,
而且不需要flush方法也是可以保存进数据库的。

另外一个实体与这个实体唯一不同的是,那个实体,主键是(id),Integer类型,而这个实体则是String(versionSequence),类型,(存放uuid类型)

关于hibernate的save方法无效的问题
引用 5 楼 baohuan_love 的回复:

我我可以把我的经验跟你讲一下,哈,经验如下:
如果如果实体的主键已经注解为自动生成,那么这个时候你在save之前再去设置这个主键,那么保存就会失败,如果需要主动设置,则把实体里自动生成主键的注解去掉。

1、我是主键自动生成uuid类型的,
我save的时候并没有设置这个主键。
2、让我奇怪的是,我另外一个实体这样保存是可以的,
而且不需要flush方法也是可以保存进数据库的。

另外一个实体与这个实体唯一不同的是,那个实体,主键是(id),Integer类型,而这个实体则是String(versionSequence),类型,(存放uuid类型)

关于hibernate的save方法无效的问题
85分
1.flush的问题
  如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。
2.saveorupdate的问题
在执行的时候hibernate会检查,如果对象在数据库中已经有对应的记录(是指主键),则会更新update,否则会添加数据save
你看下每次生成的主键是不是一样的,把表数据清空,重新试下saveorupdate方法是否能保存到库表
关于hibernate的save方法无效的问题
引用 8 楼 EverWHL 的回复:

1.flush的问题
  如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。
2.saveorupdate的问题
在执行的时候hibernate会检查,如果对象在数据库中已经有对应的记录(是指主键),则会更新update,否则会添加数据save
你看下每次生成的主键是不是一样的,把表数据清空,重新试下saveorupdate方法是否能保存到库表

确实是第一条,如果主键生成策略是uuid等不是由数据库生成的,则session.save()时并不会发出SQL语句,只有flush时才会发出SQL语句,但如果主键生成策略是native由数据库生成的,则session.save的同时就发出SQL语句。

这个问题。3Q


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于hibernate的save方法无效的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!