Domanda

Ho uno stack Spring/JPA/Groovy/Hibernate, (Nota: non graals), e sto scoprendo che sto ricevendo un No session found for current thread Quando si cerca di eseguire un po ' @Transactional lavorare sull'avvio.

Ho una classe di controller che, su @PostConstruct, invoca a @Transactional Metodo su un'altra classe che cerca di popolare il database con alcuni dati di esempio da utilizzare in una simulazione.

Ecco il controller classe:

@Component
public class SimulationController {

    private TransactionTemplate transactionTemplate;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private IPublisher publisher;

    @PostConstruct
    public void intialize()
    {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                racePublisher.populateData();
            }
        });
    }
    //  Also tried, with no success:    
    //  @PostConstruct
    //  public void initialize()
    //  {
    //      publisher.populateData();
    //  }
}

Come puoi vedere, mi sono allontanato da un puro @Transactional approccio nel @PostConstruct Per ragioni discusse qui.

Mio IPublisher è una classe groovy, come segue:

@Component
class Publisher implements IPublisher {

@Autowired
IStockDAO stockDAO

void populateData()
{
    createStock()
}
@Transactional
void createStock()
{
    def list = [new Stock(ticker: "ADBE", name: "Adobe"),
                new Stock(ticker: "MSFT", venueCode: "Microsoft")]
    list.each { stockDAO.create it }
}

Che è un'implementazione di:

public interface IPublisher {

    public void populateData();
    public void createStock();
}

Nota, ho anche provato a contrassegnare populateData() come @Transactional, senza alcun effetto.

Nella mia classe di contesto di primavera, sto definendo <tx:annotation-driven/>.

Per quanto ne so, ho fatto tutto correttamente. Tuttavia, non riesco a farlo funzionare.

Cos'altro è richiesto?

Aggiornato:Ecco i fagioli che impostano i miei fagioli relativi al dataAccess:

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

    <tx:annotation-driven/>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://${database.host}:${database.port}/${database.name}" />
        <property name="username" value="${database.username}" />
        <property name="password" value="${database.password}" />
        <property name="initialSize" value="5" />
        <property name="maxActive" value="50" />
    </bean>
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.mangofactory.concorde</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop><!--  use create for full drop/create -->
                <prop key="hibernate.connection.autocommit">true</prop>
                <prop key="hibernate.statement_cache.size">0</prop>
                <prop key="hibernate.jdbc.batch_size">20</prop>
            </props>
        </property>
    </bean>
    <beans>
È stato utile?

Soluzione

Dovresti usare HibernateTransactionManager invece di DataSourceTransactionManager.

Altri suggerimenti

Ci sono problemi di base con il codice. Il confine transazionale inizia nel metodo createstock della classe dell'editore e finisce lì. Non si propaga al tuo controller. Utilizzare le chiamate di query DB all'interno di una transazione. cioè all'interno di un metodo che ha l'annotazione transazionale. Altrimenti non funzionerebbe mai.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top