我有一個交易問題,註釋一個服務,用@Transactional調用一個DAO拋出一個異常,說明會話未打開。我可以通過@Transactional註釋DAO來實現它的唯一方法。究竟會發生什麼?交易不工作,除非內部DAO
這是我想要做什麼,但不工作:
class CustomerService {
private CustomerDao dao;
@Transactional
public void foo() {
int customerId = dao.getCustomer("fred");
}
}
class CustomerDao {
private HibernateTemplate hibernateTemplate;
public int getCustomer(String name) {
String sql = "SELECT {m.*} from Customers {m} where name=:name";
Query qry = getSession().createSQLQuery(sql).addEntity("m", Customer.class);
qry.setParameter("name", name);
qry.setCacheable(false);
List<Customer> list = qry.list();
return list.iterator().next().getId();
}
private Session getSession() {
return hibernateTemplate.getSessionFactory().getCurrentSession();
}
}
這是我在做什麼,而不是,但寧可不要到:
class CustomerService {
private CustomerDao dao;
public Customer(CustomerDao dao) {
this.dao = dao;
}
public void foo() {
int customerId = dao.getCustomer("fred");
}
}
class CustomerDao {
private HibernateTemplate hibernateTemplate;
@Transactional
public int getCustomer(String name) {
String sql = "SELECT {m.*} from Customers {m} where name=:name";
Query qry = getSession().createSQLQuery(sql).addEntity("m", Customer.class);
qry.setParameter("name", name);
qry.setCacheable(false);
List<Customer> list = qry.list();
return list.iterator().next().getId();
}
private Session getSession() {
return hibernateTemplate.getSessionFactory().getCurrentSession();
}
}
問題似乎是由CustomerService在包裝類的構造函數中實例化引起的,其中包裝在Spring xml上下文文件中聲明:
class AllServices {
private final CustomerService customerService;
private final OrderService orderService;
@Autowired
public AllServices(CustomerDao customerDao, OrderDao orderDao) {
this.customerService = new CustomerService(customerDao);
this.orderService = new OrderService(orderDao);
}
public CustomerService getCustomerService() {
return this.customerService;
}
public OrderService getOrderService() {
return this.orderService;
}
}
彈簧文件看起來是這樣的:
<context:annotation-config />
<import resource="classpath:db-spring-conf.xml"/>
<bean id="allServices" class="myPackage.AllServices" />
和DB-彈簧的conf:
<bean id="editorDatasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${versioning.db}" />
<property name="username" value="${versioning.user}" />
<property name="password" value="${versioning.pass}" />
</bean>
<tx:annotation-driven transaction-manager="editorTransactionManager"/>
<bean id="editorSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="editorDatasource"/>
<property name="exposeTransactionAwareSessionFactory">
<value>true</value>
</property>
<property name="annotatedClasses">
<list>
<value>myPackage.Order</value>
</list>
</property>
<property name="mappingResources">
<list>
<value>mappings/customer.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!-- Enable Query Cache -->
<prop key="hibernate.cache.use_query_cache">false</prop>
<!-- Enable 2nd Level Cache -->
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean id="editorHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="editorSessionFactory"/>
</bean>
<bean id="editorTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="editorSessionFactory" />
</bean>
<!-- DAOs -->
<bean id="customerDao" class="myPackage.CustomerHibernateDao" />
<bean id="orderDao" class="myPackage.OrderHibernateDao" />
現在我已經感動的CustomerService的實例到Spring配置文件和一切工作的對待。所有使用@Transactional的類都必須位於上下文文件中嗎?另外,爲了使工作我不得不創建的CustomerService接口,以防止異常,同時加載上下文文件 - Could not generate CGLIB subclass of class
也許交易方面不適用於'CustomerService'。顯示它是如何配置的。 – axtavt 2010-09-08 17:13:30
請顯示您的spring xml配置 – Vadeg 2010-09-08 17:47:34