目录
1. 抛javax.persistence.TransactionRequiredException异常如果没有事务时
2. save/insert/delete相关的DB操作没有生效也没有错误
3. java.lang.ClassCastException
版本
Library | Current | Upgraded |
Hibernate-core | 3.6.10.Final | 5.4.18.final |
Hibenrate-valicator | 4.2.0.Final | 6.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;
/