Hibernate不支持PostgreSQL的for update nowait的解决方法

本文介绍如何通过自定义Dialect使Hibernate支持PostgreSQL的forupdatenowait语法,包括重写PostgreSQLDialect类及配置文件的修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前,Hibernate对PostgreSQL的for update nowait语法是不支持的,(Hibernate3.2.4),由于项目的需要,只好自己来实现。Hibernate在解析SQL文的时候,利用的是Hibernate的Dialect,我们可以通过重载org.hibernate.dialect.PostgreSQLDialect来实现对for update nowait的支持。

1.重载PostgreSQLDialect
只需要重写getForUpdateNowaitString()即可
import org.hibernate.dialect.PostgreSQLDialect;

public class MyPostgreSQLDialect extends PostgreSQLDialect {

    @Override
    
public String getForUpdateNowaitString() {
        
return " for update nowait";
    }

   
}


2.修正Hibernate设定文件(hibernate.cfg.xml)


<hibernate-configuration>
    
<session-factory>
        
<property name="connection.driver_class">org.postgresql.Driver</property>
        
<property name="connection.url">jdbc:postgresql:/localhost/sample</property>
        
<property name="connection.username">guest</property>
        
<property name="connection.password">guest</property>
        
<property name="show_sql">true</property>
        
<property name="dialect">test.MyPostgreSQLDialect</property> ← 修正这里
        
<mapping resource="test/Test.hbm.xml"/>
    
</session-factory>
</hibernate-configuration>

3.如果利用Spring去连接Hibernate,则在Sping的applicationContext.xml文件中要做以下修正

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    
<property name="dataSource">
        
<ref local="dataSource"/>
    
</property>
    
<property name="configLocation">
        
<value>WEB-INF/classes/koichi/hibernate.cfg.xml</value>
    
</property>
    
<property name="configurationClass">
        
<value>org.hibernate.cfg.AnnotationConfiguration</value>
    
</property>
    
<property name="hibernateProperties">
        
<props>
            
<prop key="hibernate.show_sql">true</prop>
            
<prop key="hibernate.dialect">test.MyPostgreSQLDialect</prop> ← 这里需要修改
        
</props>
    
</property>
</bean>

3.nowait的代码实现
只需要指定LockMode.UPGRADE_NOWAIT即可。

HogeDTO dto 
= (HogeDTO) getHibernateTemplate().
                            load(HogeDTO.
class, hogeid, LockMode.UPGRADE_NOWAIT);

发生Lock错误的时候,会报出以下消息:

 Caused by: org.postgresql.util.PSQLException: ERROR: could not obtain lock on row in relation 
"hoge"
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:
1512)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:
1297)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:
188)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:
437)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:
353)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:
257)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:
92)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:
137)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:
1676)
    at org.hibernate.loader.Loader.doQuery(Loader.java:
662)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:
223)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:
1782)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:
93)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:
81)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:
2729)
    at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:
365)
    at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:
346)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:
123)
    at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:
272)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:
90)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:
809)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:
792)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:
787)
    at org.springframework.orm.hibernate3.HibernateTemplate$
3.doInHibernate(HibernateTemplate.java:478)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:
358)
    ... 
77 more

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值