我在打开Hibernate事务时遇到了麻烦。
这是配置:
<context:annotation-config />
<context:component-scan base-package="com.cinebot" />
<mvc:annotation-driven />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.cinebot.db.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
这是错误的代码:
@Transactional
public static <T> T get(Class<T> classe, Serializable id) throws Exception {
if(id==null) return null;
T obj = (T) HibernateUtil.getSessionFactory().getCurrentSession().get(classe, id);
return obj;
}
这是一个例外:
org.hibernate.HibernateException: get is not valid without active transaction
这是一个例子:
package com.cinebot.db.entity;
// Generated 3-lug-2012 10.31.04 by Hibernate Tools 3.4.0.CR1
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Dettagli generated by hbm2java
*/
@Entity
@Table(name = "dettagli", catalog = "cinebot")
public class Dettagli implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String nome;
private String valore;
public Dettagli() {
}
public Dettagli(String nome) {
this.nome = nome;
}
public Dettagli(String nome, String valore) {
this.nome = nome;
this.valore = valore;
}
@Id
@Column(name = "nome", unique = true, nullable = false, length = 32)
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
@Column(name = "valore", length = 65535)
public String getValore() {
return this.valore;
}
public void setValore(String valore) {
this.valore = valore;
}
}
我无法理解为什么没有使用@Transactional注释来自动打开事务。我错过了什么?
由于
答案 0 :(得分:1)
刚看过这段代码,显然无法使用Spring事务注释。
您正在使用静态方法并从静态持有者处获取SessionFactory。
您需要从Spring获取DAO实例,该实例与SessionFactory的Spring实例连接。这将允许Spring代理DAO并提供事务行为。
答案 1 :(得分:1)
根据评论你可以重新检查以下几点(虽然我不建议使用相同的)
我建议在Controller和DAO之间使用服务层。将服务方法注释为@transactional,它调用DAO中的方法。请记住,您不应该为了调用其中的方法而创建任何bean的新实例,而是注入/自动装配Service-&gt; Controller和DAO-&gt; Service。