Tobia
Tobia

Reputation: 9506

Get is not valid without active transaction

i have a trouble opening Hibernate transaction.

This is the configuration:

    <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 />

And this is the faulty code:

@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;
}

This is the exception:

org.hibernate.HibernateException: get is not valid without active transaction

This is an example entitiy:

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;
    }

}

I can not understand why is not enought the @Transactional annotation to auto-open the transaction. What i missed?

Thanks

Upvotes: 0

Views: 4169

Answers (2)

Sunil Chavan
Sunil Chavan

Reputation: 3004

Based on the comments You can recheck below points(though I would not recommend using same)

  • You need to inject/autowire spring DAO into your controller. Annotate the DAO with @Repository
  • Make sure your spring scans and create bean for your DAO class which is done by context:component-scan. Here your dao class should be inside the given package/subpackage.

I would recommend to use service layer between your Controller and DAO. Annotate the service method as @transactional which calls method in DAO. Remember you should not create new instance of any bean in order to call methods in it but inject/autowire Service->Controller and DAO->Service.

Upvotes: 1

Alex Barnes
Alex Barnes

Reputation: 7218

Just having had a look at this code, it's clearly not going to work with Spring transactional annotations.

You're using a static method and getting your SessionFactory from a static holder.

You need to obtain an instance of your DAO from Spring which is wired with the Spring instance of the SessionFactory. This will allow Spring to proxy the DAO and provide the transactional behaviour.

Upvotes: 1

Related Questions