gpt4 book ai didi

java - Spring/Hibernate/HSQLDB 组合的 session /事务问题

转载 作者:行者123 更新时间:2023-12-01 13:30:29 25 4
gpt4 key购买 nike

出于培训目的,我目前正在重写我的应用程序,以使用 Spring 和 Hibernate 的组合来访问我的本地 HSQLDB,而不是仅通过 JDBC 来访问。

我认为我已经完成了大部分工作,当我出于测试目的在主要方法上执行一些方法时,一切似乎都工作正常。但是,一旦我想通过 @Transactional 启用事务处理,整个事情就会停止工作,告诉我不存在连接。

我已经尝试了 stackoverflow 上类似问题中给出的一些解决方案,但没有一个对我有用。

首先是完整的堆栈跟踪:http://pastebin.com/ACkp7Ysj

这是我的类和配置文件:

数据源配置:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="url" value="jdbc:hsqldb:file:C:\\dev\\source\\productionDB\\productionDB;shutdown=true" />
<property name="username" value="admin" />
<property name="password" value="admin" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="exercise.java.basics.storage" />

<property name="mappingLocations">
<list>
<value>classpath:hibernate/Warehouse.hbm.xml</value>

</list>
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>

</bean>

<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

<tx:annotation-driven transaction-manager="txManager"/>

</beans>

DAO 配置:

<beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">

<bean id="warehouseDAO" class="exercise.java.basics.storage.WarehouseDAOImpl">
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory"/>

</bean>

</beans>

模块配置:

 <beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">

<import resource="database/Spring-Datasource.xml" />
<import resource="warehouse/Spring-Warehouse.xml" />

</beans>

hibernate 映射:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="exercise.java.basics.storage.WarehouseNew" table="WAREHOUSE">
<id name="product_ID" type="integer">
<column name="product_ID" not-null="true"/>
<generator class="identity" />
</id>
<property name="product_name" type="string">
<column name="product_name" length="100"/>
</property>
<property name="product_count" type="integer">
<column name="product_count"/>
</property>
</class>
</hibernate-mapping>

DAO 模式:

public interface WarehouseDAO {

public void initializeWarehouse();

public void storeProducts( final Product product, final int count );

public void removeProducts( final Product product, final int count );

public void updateStock();

}

DAO 实现:

@Transactional
@Repository
public class WarehouseDAOImpl implements WarehouseDAO {

private DataSource dataSource;

@Autowired
private SessionFactory sessionFactory;

public void setDataSource( final DataSource dataSource ) {
this.dataSource = dataSource;
}

public void setSessionFactory( final SessionFactory sessionFactory ) {
this.sessionFactory = sessionFactory;
}

public void initializeWarehouse() {

String initProductsSQL = "INSERT INTO WAREHOUSE(product_name, product_count) VALUES (?, 0)";

Connection conn = null;

try {

conn = DataSourceUtils.getConnection( this.dataSource );

Statement stmt = conn.createStatement();

PreparedStatement ps = conn.prepareStatement( initProductsSQL );
ps.setString( 1, String.valueOf( Product.NAIL ) );
ps.executeUpdate();
ps.setString( 1, String.valueOf( Product.SCREW ) );
ps.executeUpdate();
ps.setString( 1, String.valueOf( Product.FINALPRODUCT ) );
ps.executeUpdate();
ps.close();

} catch ( SQLException e ) {
throw new RuntimeException( e );

} finally {
if ( conn != null ) {
try {
conn.close();
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}

}

public void storeProducts( final Product product, final int count ) {

String updateProductCountSQL = "UPDATE WAREHOUSE SET product_count = product_count + " + count
+ " WHERE product_name = '" + product + "'";

Connection conn = null;

try {

conn = DataSourceUtils.getConnection( this.dataSource );

Statement stmt = conn.createStatement();
stmt.execute( updateProductCountSQL );
stmt.close();

} catch ( SQLException e ) {
throw new RuntimeException( e );

} finally {
if ( conn != null ) {
try {
conn.close();
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}

}

public void removeProducts( final Product product, final int count ) {

String updateProductCountSQL = "UPDATE WAREHOUSE SET product_count = product_count - " + count
+ " WHERE product_name = '" + product + "'";

Connection conn = null;

try {

conn = DataSourceUtils.getConnection( this.dataSource );

Statement stmt = conn.createStatement();
stmt.execute( updateProductCountSQL );
stmt.close();

} catch ( SQLException e ) {
throw new RuntimeException( e );

} finally {
if ( conn != null ) {
try {
conn.close();
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}

}

public void updateStock() {

String getUpdatedStocksSQL = "SELECT * FROM WAREHOUSE WHERE product_name = ? ;";

Connection conn = null;

try {

conn = DataSourceUtils.getConnection( this.dataSource );

PreparedStatement ps = conn.prepareStatement( getUpdatedStocksSQL );

WarehouseNew warehouse = exercise.java.basics.storage.WarehouseNew.getInstance();

ps.setString( 1, String.valueOf( Product.NAIL ) );
ResultSet rsNail = ps.executeQuery();
ps.setString( 1, String.valueOf( Product.SCREW ) );
ResultSet rsScrew = ps.executeQuery();
ps.setString( 1, String.valueOf( Product.FINALPRODUCT ) );
ResultSet rsFinalProduct = ps.executeQuery();

rsNail.next();
rsScrew.next();
rsFinalProduct.next();

warehouse.setNailCount( rsNail.getString( 3 ) );
warehouse.setScrewCount( rsNail.getString( 3 ) );
warehouse.setFinalProductCount( rsNail.getString( 3 ) );

//Debug
System.out.println( rsNail.getInt( 3 ) );
System.out.println( rsScrew.getInt( 3 ) );
System.out.println( rsFinalProduct.getInt( 3 ) );

rsNail.close();
rsScrew.close();
rsFinalProduct.close();
ps.close();

} catch ( SQLException e ) {
throw new RuntimeException( e );
} finally {
if ( conn != null ) {
try {
conn.close();
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}

}

public static void main( final String[] args ) {

ApplicationContext context = new ClassPathXmlApplicationContext( "Spring-Module.xml" );

WarehouseDAO warehouseDAO = (WarehouseDAO) context.getBean( "warehouseDAO" );

// warehouseDAO.initializeWarehouse();
warehouseDAO.updateStock();

warehouseDAO.storeProducts( Product.NAIL, 10 );
warehouseDAO.storeProducts( Product.SCREW, 20 );
warehouseDAO.storeProducts( Product.FINALPRODUCT, 30 );

warehouseDAO.updateStock();

}
}

模型类:

public class WarehouseNew {

private int nailCount;
private int screwCount;
private int finalProductCount;
private int product_ID;

private String product_name;
private int product_count;

private static volatile WarehouseNew instance = null;

public static WarehouseNew getInstance() {
if ( instance == null ) {
synchronized ( WarehouseNew.class ) {
if ( instance == null ) {
instance = new WarehouseNew();
}
}
}

return instance;
}

/**
* Constructor for ...
*/
private WarehouseNew() {

}

/**
* @return the nailCount
*/
public int getNailCount() {
return this.nailCount;
}

/**
* @param string the nailCount to set
*/
public void setNailCount( final String string ) {
this.nailCount = Integer.parseInt( string );
}

/**
* @return the screwCount
*/
public int getScrewCount() {
return this.screwCount;
}

/**
* @param string the screwCount to set
*/
public void setScrewCount( final String string ) {
this.screwCount = Integer.parseInt( string );
}

/**
* @return the finalProductCount
*/
public int getFinalProductCount() {
return this.finalProductCount;
}

/**
* @param string the finalProductCount to set
*/
public void setFinalProductCount( final String string ) {
this.finalProductCount = Integer.parseInt( string );
}

/**
* @return the product_id
*/
public int getProduct_ID() {
return this.product_ID;
}

/**
* @param product_id the product_id to set
*/
public void setProduct_ID( final int product_ID ) {
this.product_ID = product_ID;
}

/**
* @return the product_name
*/
public String getProduct_name() {
return this.product_name;
}

/**
* @param product_name the product_name to set
*/
public void setProduct_name( final String product_name ) {
this.product_name = product_name;
}

/**
* @return the product_count
*/
public int getProduct_count() {
return this.product_count;
}

/**
* @param product_count the product_count to set
*/
public void setProduct_count( final int product_count ) {
this.product_count = product_count;
}

}

我希望有人能指出我正确的方向。 Spring 框架和 Hibernate 对我来说是全新的,我只是希望它能够工作。

我真的不明白为什么当我不使用 @Transactional 注释时数据库访问会起作用,但随后又说使用它时没有连接......对我来说毫无意义。

最诚挚的问候达扎

编辑:根据使用 sessionFactory 的建议进行更改。但错误仍然相同。

// Experimental

this.sessionFactory.getCurrentSession().doWork(

new Work() {
public void execute( final Connection connection ) throws SQLException {
try {

String getUpdatedStocksSQL = "SELECT * FROM WAREHOUSE WHERE product_name = ? ;";

PreparedStatement ps = connection.prepareStatement( getUpdatedStocksSQL );

WarehouseNew warehouse = exercise.java.basics.storage.WarehouseNew.getInstance();

ps.setString( 1, String.valueOf( Product.NAIL ) );
ResultSet rsNail = ps.executeQuery();
ps.setString( 1, String.valueOf( Product.SCREW ) );
ResultSet rsScrew = ps.executeQuery();
ps.setString( 1, String.valueOf( Product.FINALPRODUCT ) );
ResultSet rsFinalProduct = ps.executeQuery();

rsNail.next();
rsScrew.next();
rsFinalProduct.next();


warehouse.setNailCount( rsNail.getString( 3 ) );
warehouse.setScrewCount( rsNail.getString( 3 ) );
warehouse.setFinalProductCount( rsNail.getString( 3 ) );

System.out.println( rsNail.getInt( 3 ) );
System.out.println( rsScrew.getInt( 3 ) );
System.out.println( rsFinalProduct.getInt( 3 ) );

rsNail.close();
rsScrew.close();
rsFinalProduct.close();
ps.close();

} catch ( SQLException e ) {
throw new RuntimeException( e );
} finally {
if ( connection != null ) {
try {
connection.close();
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}
}
} );

// !Experimental

最佳答案

我认为您的 jdbc 驱动程序 URL 不正确:

对于 HSQL 来说是

org.hsqldb.jdbcDriver

你似乎有

<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />

这是一个 MS-SQL/Sybase 驱动程序类。

您的 @Transaction 注释此时失败的主要原因是您正在使用 hibernate 事务管理器(因此仅在您开始使用 session 工厂时才起作用)。

<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

为了使旧的 jdbc 代码正常工作,您需要使用类似的东西:

<bean id="txManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

另一种方法是将 DataSourceUtils.getConnection( this.dataSource 替换为 sessionFactory.getCurrentSession().connection()。这实际上是 deprectated 所以你最好使用 sessionFactory.getCurrentSession.doWork() 来代替。

关于java - Spring/Hibernate/HSQLDB 组合的 session /事务问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21598773/

25 4 0
文章推荐: java - 自动将变量写入子类
文章推荐: java - 如何在 java 中将 list 转换为 list