java - 使用休眠当前会话执行存储过程后无法执行任何读/写操作
问题描述
使用Hibernate(版本 5.4.2.final)执行以下方法(包含SQL Server 过程)时,我看到了行为上的差异 getCurrentSession()
public List<A> notWorkingA() {
Session session = sessionFactory.getCurrentSession();
session.doWork(connection -> {
try(CallableStatement callableStatement = connection.prepareCall("{ call PROCEDURE_WITH_NO_OUTPARAM() }")){
callableStatement.execute();
}
});
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = builder.createQuery(A.class);
Root<A> rootObject = criteriaQuery.from(A.class);
Predicate mainPredicate = builder.and(
builder.equal(rootObject.get("p1"), 1),
builder.equal( rootObject.get("p2"), "SOMEVALUE")
);
criteriaQuery.select(rootObject).where(mainPredicate);
Query<A> query = session.createQuery(criteriaQuery);
return query.getResultList();
}
public List<A> workingA() {
Session session = sessionFactory.openSession();
session.doWork(connection -> {
try(CallableStatement callableStatement = connection.prepareCall("{ call PROCEDURE_WITH_NO_OUTPARAM() }")){
callableStatement.execute();
}
});
SessionFactoryUtils.closeSession(session);
session = sessionFactory.getCurrentSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = builder.createQuery(A.class);
Root<A> rootObject = criteriaQuery.from(A.class);
Predicate mainPredicate = builder.and(
builder.equal(rootObject.get("p1"), 1),
builder.equal( rootObject.get("p2"), "SOMEVALUE")
);
criteriaQuery.select(rootObject).where(mainPredicate);
Query<A> query = session.createQuery(criteriaQuery);
return query.getResultList();
}
public List<A> notWorkingB() {
Session session = sessionFactory.getCurrentSession();
session.doWork(connection -> {
try(CallableStatement callableStatement = connection.prepareCall("{ call PROCEDURE_WITH_OUTPARAM() }")){
callableStatement.registerOutParameter(1, Types.VARCHAR);
callableStatement.execute();
}
});
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = builder.createQuery(A.class);
Root<A> rootObject = criteriaQuery.from(A.class);
Predicate mainPredicate = builder.and(
builder.equal(rootObject.get("p1"), 1),
builder.equal( rootObject.get("p2"), "SOMEVALUE")
);
criteriaQuery.select(rootObject).where(mainPredicate);
Query<A> query = session.createQuery(criteriaQuery);
return query.getResultList();
}
public List<A> workingB() {
Session session = sessionFactory.getCurrentSession();
session.doWork(connection -> {
try(CallableStatement callableStatement = connection.prepareCall("{ call PROCEDURE_WITH_OUTPARAM() }")){
callableStatement.registerOutParameter(1, Types.VARCHAR);
callableStatement.execute();
log.info(callableStatement.getString(1));
}
});
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = builder.createQuery(A.class);
Root<A> rootObject = criteriaQuery.from(A.class);
Predicate mainPredicate = builder.and(
builder.equal(rootObject.get("p1"), 1),
builder.equal( rootObject.get("p2"), "SOMEVALUE")
);
criteriaQuery.select(rootObject).where(mainPredicate);
Query<A> query = session.createQuery(criteriaQuery);
return query.getResultList();
}
执行时notWorkingA()
&给出以下错误notWorkingB()
的行query.getResultList()
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The server failed to resume the transaction. Desc:6e00000008.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:251)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:81)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:36)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$1ConnectionCommand.doExecute(SQLServerConnection.java:1835)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:6276)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1794)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(SQLServerConnection.java:1840)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.rollback(SQLServerConnection.java:2043)
at com.mchange.v2.c3p0.impl.NewProxyConnection.rollback(NewProxyConnection.java:860)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116)
... 49 more
经过一些调试后,我得到了修复,如果notWorkingB()
它调用它会起作用(但不了解根本原因)。但是在 的情况下,由于它是没有输出参数的过程,所以我不能在这里做这个解决方法,如果它使用as in它将起作用。 callableStatement.getString(1)
workingB()
notWorkingA()
openSession()
workingA()
所以我想知道这个问题的根本原因是什么。另外,由于事务是在Filter中管理的,因此我该如何notWorkingA()
与自己一起工作。currentSession()
注意:
这种情况在Hibernate 3中可以正常工作。仅在迁移到Hibernate 5后才会出现问题
解决方案
推荐阅读
- typescript - Protractor Headless Chrome 无法下载文件
- python - 如何使用python在给定一些条件的excel中获取名称字段?
- latex - Latex:描述列表 [style=nextline] 在包含枚举列表时无法按预期工作
- android - 最新的 android vision 版本中缺少 CameraSource.Builder setFlashMode 方法
- r - 按组计算描述性统计
- python - 变量在 for 循环中未正确重新定义(Python)
- android - 完美运行一段时间后,应用程序崩溃
- c++ - C++ 性能 std::array 与 std::vector
- algorithm - 最小化在池中解决债务的交易成本
- c# - 在 Hololens 上的 C# Unity 中找不到模块 C++ .dll