0
点赞
收藏
分享

微信扫一扫

Hibernate升级到5.4.18.final的过程踩过的坑

杰森wang 2022-01-20 阅读 22

目录

1. 抛javax.persistence.TransactionRequiredException异常如果没有事务时

2. save/insert/delete相关的DB操作没有生效也没有错误

3. java.lang.ClassCastException

4. org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [xxx] 

5. org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

6.  org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported; use JPA-style ordinal parameters (e.g., `?1`) instead

7.  主键唯一性约束


版本

LibraryCurrentUpgraded
Hibernate-core3.6.10.Final5.4.18.final
Hibenrate-valicator4.2.0.Final6.1.5.final

1. 抛javax.persistence.TransactionRequiredException异常如果没有事务时

javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:413)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1608)
at .....

错误出现的Code 

	NativeQuery sql = session.createSQLQuery(query);
				sql.setProperties(params);
                sql.setFlushMode(FlushMode.MANUAL);
				return sql.executeUpdate();

原因是:Hibernate 现在符合 JPA 规范,不允许在事务边界之外刷新更新。

解决方法一: 加下面系统参数允许在是事务之外做更新操作。

hibernate.allow_update_outside_transaction=true

解决方法二: 在相关的方法上加@Transational 注解

参考资料是hibernate-orm/migration-guide.adoc at 5.2 · hibernate/hibernate-orm · GitHub

2. save/insert/delete相关的DB操作没有生效也没有错误

相关Hibernate的代码如下:

session.saveOrUpdate(obj);

 session.merge(entity);

解决方法一: 加@Transational 注解在相关的方法上面

解决方法二: 加下面系统参数

hibernate.allow_update_outside_transaction=true

而且如果没有事务的话,要在增删改操作后面调用flush()方法

//session.saveOrUpdate(obj);
//session.merge(obj);
if(!session.getTransaction().isActive()) {
   session.flush();
}

3. java.lang.ClassCastException

java.lang.ClassCastException: com.sun.proxy.$Proxy217 cannot be cast to org.hibernate.engine.spi.SessionImplementor
at org.hibernate.criterion.DetachedCriteria.getExecutableCriteria(DetachedCriteria.java:67)

原因是spring用了CGLIB 代理

解决方法一

把 template.execute(callback) 替换为template.executeWithNativeSession(callback)方法.

//template.execute(callback) 
template.executeWithNativeSession(callback)

在executeWithNativeSession方法里会会把做转换。

解放方法二:

4. org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [xxx] 

Caused by: org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [NULL] during auto-discovery of a native-sql query
        at org.hibernate.loader.custom.CustomLoader.validateAliases(CustomLoader.java:520)
        at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:497)
        at org.hibernate.loader.Loader.preprocessResultSet(Loader.java:2357)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2313)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2064)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2026)
        at org.hibernate.loader.Loader.doQuery(Loader.java:951)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:352)
        at org.hibernate.loader.Loader.doList(Loader.java:2857)
        at org.hibernate.loader.Loader.doList(Loader.java:2839)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2671)
        at org.hibernate.loader.Loader.list(Loader.java:2666)
        at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
        at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2139)
        at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1163)
        at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:173)
        at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)

问题代码

select .... ,null,null from table_name

解决方法:

select .... ,null as column2 ,null as column2 from table_name

5. org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

错误信息

org.springframework.orm.hibernate5.HibernateSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
        at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:300) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
        at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:388) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
        at org.springframework.orm.hibernate5.HibernateTemplate.execute(HibernateTemplate.java:337) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]

....

Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
        at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:143) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
        at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:475) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
        at org.hibernate.envers.AuditReaderFactory.get(AuditReaderFactory.java:38) ~[hibernate-envers-5.4.18.Final.jar!/:5.4.18.Final]
错误原因

  由错误提示可知,是不能获取事物同步Session

解决办法: 添加一个注解@Transactional在相关方法上, 例如下面代码

@Repository("studentDao")
@Transactional
public class StudentDaoImpl implements StudentDao
{

}

6.  org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported; use JPA-style ordinal parameters (e.g., `?1`) instead

错误信息

java.lang.IllegalArgumentException: org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported; use JPA-style ordinal parameters (e.g., `?1`) instead : xxxx此处省略涉及公司表的结果]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.hibernate5.HibernateTemplate$CloseSuppressingInvocationHandler.invoke(HibernateTemplate.java:1228)
at com.sun.proxy.$Proxy194.createQuery(Unknown Source)

java.lang.IllegalArgumentException: Could not locate ordinal parameter [0], expecting one of [1, 2, 3, 4, 5, 6, 7]
at org.hibernate.query.internal.ParameterMetadataImpl.getOrdinalParameterDescriptor(ParameterMetadataImpl.java:154) ~[hibernate-core-...
at org.hibernate.query.internal.NativeQueryImpl.setParameter(NativeQueryImpl.java:613) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.query.internal.NativeQueryImpl.setParameter(NativeQueryImpl.java:62) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]

错误代码例如

SELECT u FROM User u WHERE u.userID = ?

原因是:hibernate 要遵守JPA标准, ?不是JPA的标准,

解决方法一: 使用JPA-Style ordinal parameters

SELECT u FROM User u WHERE u.userID = ?1

解决方法二: 使用 named parameters

SELECT u FROM User u WHERE u.userID = :userId

当然这种方法相应的代码也要改。再设置参数的适合按名字设置。

//SQLQuery sql = session.createSQLQuery(query);
// sql.setParameters(value, type);
SQLQuery sql = session.createSQLQuery(query);
sql.setParameter("userId" value, type);

7.  主键唯一性约束

[https-jsse-nio-auto-1-exec-4](org.hibernate.engine.jdbc.spi.SqlExceptionHelper:137) - SQL Error: 1, SQLState: 23000
 ERROR[https-jsse-nio-auto-1-exec-4](org.hibernate.engine.jdbc.spi.SqlExceptionHelper:142) - ORA-00001: unique constraint (ASPEN.SYS_C00610415) violated

相关代码

解决方法:基于表中最大的主键重建Sequence.  当然你也可以用你自己的方法重建。

--/
declare
maxval number;
begin
select max(pk_user_id) + 2 into maxval from user;
execute immediate 'DROP SEQUENCE SEQ_USER_ID ';
execute immediate 'CREATE SEQUENCE SEQ_USER_ID INCREMENT BY 1 START WITH '|| maxval ||' MAXVALUE 999999999999999999999999999 ';
end;
/

举报

相关推荐

0 条评论