我正在使用Spring 3.14和hibernate 3.6.10开发后端服务器(当然还有很多其他库,但我认为那些在这种情况下最重要)。服务器被几个客户端使用,其中一个是android,由于android代码中的错误(一个接一个不必要多次调用后端)我检测到我的服务器中的错误,我无法解决到目前为止浪费时间几天。所以问题是,当我运行多个数据库查询(确切地说是命名查询)时,我收到了一个错误。真正有趣的是错误有所不同!有一次我在hibernate调用“关闭连接”(堆栈跟踪1)上得到NPE,另一个我得到“语句已经关闭没有进一步的信息” - 堆栈2.我看到了更多,但似乎所有似乎都出现,因为语句已被释放。为了让您了解我正在做什么来获得结果,我将代码粘贴在最底层。还请在堆栈跟踪下方找到我的配置的粘贴。
所以回顾一下。当异步进行多个DB连接时,应用程序失败。经过近两天的思考和尝试,我放弃了。也许有人会帮助我,我会很感激......
无论如何,这里有所有配置和一段代码。
的applicationContext:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
bool over = false;
while (over != true)
{
names.Add(Console.ReadLine());
if(typedName == "0")
{
over = true;
}
}
Console.WriteLine("Entered names : ");
names.ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}
的persistence.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/testSchema"
p:username="train_together" p:password="..." p:initialSize="5" p:maxActive="10">
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="validate" />
<entry key="hibernate.enable_lazy_load_no_trans" value="true" />
<entry key="hibernate.connection.release_mode" value="after_transaction" />
</map>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:component-scan base-package="com.train"/>
<context:spring-configured />
<context:annotation-config />
<tx:annotation-driven />
正如我所说,问题出现在同一时间运行的多个查询中,所以我只创建了新的REST端点,它运行两个带有非常简单的命名查询的线程。
这是我的休息方法:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="JpaPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate" value="thread" />
</properties>
</persistence-unit>
</persistence>
UserDAO支持基础dao:
@GET
@Path("1")
public Response test1(@QueryParam("i") @DefaultValue("10") int iterations) {
String key = UUID.randomUUID().toString().substring(0, 4);
System.out.println("*************************");
System.out.println(" request consumed: " + key);
System.out.println("*************************");
Thread t1 = new Thread(new Runnable() {
@Override public void run() {
try {
for (int i = 0; i < iterations; i++) {
System.out.println("*************************");
System.out.println("\tThread: 1 " + key + " iteration: " + (i+1));
userDao.getUsersOfTypeFromSportClub(UserType.CONTENDER, 1L);
}
} catch (Throwable e) {
System.out.println(Throwables.getStackTraceAsString(e));
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override public void run() {
try {
for (int i=0; i< iterations; i++) {
System.out.println("*************************");
System.out.println("\tThread: 2 " + key + " iteration: " + (i+1));
userDao.getUsersOfTypeFromSportClub(UserType.CONTENDER, 1L);
}
} catch (Throwable e) {
System.out.println(Throwables.getStackTraceAsString(e));
}
}
});
t1.start();
t2.start();
return Response.ok().build();
}
P.S。在我的测试中,UserDao调用的命名查询正常工作。