Transational не будет откатывать @Hibernate

1

Я пытаюсь добавить механизм отката к моему весеннему проекту, следуя нескольким учебным пособиям. Я все еще не могу решить проблему, почему откат не произойдет в следующем коде:

@Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = TransactionException.class)
    public boolean changeSquad(ArrayList<Integer> playerIdList, String email) {
        boolean squadChanged = false;

        // Obtain the current list of players from the persistent storage
        TypedQuery<Player> playersQuery = emgr.createNamedQuery("Player.getUsersPlayers", Player.class);
        playersQuery.setParameter("email", email);



        List<Player> currentPlayerList = playersQuery.getResultList();

        // Make a copy of the list obtained as method parameter
        ArrayList<Integer> playerIdListCopy = new ArrayList<Integer>(playerIdList);

        // Make a copy of the list obtained from persistent storage
        ArrayList<Player> currentPlayerListCopy = new ArrayList<Player>(currentPlayerList);
        System.out.println("current player list copy = " + currentPlayerListCopy);



        // Iterate through each player from the currentPlayerList
        for (int i = 0; i < currentPlayerListCopy.size(); i++) {
            // On each iteration check if the playerIdList contains currently iterated 
            // Player id, if so then eliminate it from both lists
            int playerId = currentPlayerListCopy.get(i).getPlayer_id();

            if (playerIdListCopy.contains(playerId)) {
                currentPlayerListCopy.remove(i);
                playerIdListCopy.remove(playerIdListCopy.indexOf(playerId));
                i--;
            }

        }
        // IF copy of current player list AND playerId list is empty, proceed
        if (currentPlayerListCopy.isEmpty() && playerIdListCopy.isEmpty()) {
            System.out.println("currentPlayerListCopy && playerIdListCopy = empty");

            // Make the squad changes

            for (int j = 0; j < currentPlayerList.size(); j++) {
                Player tempPlayer = currentPlayerList.get(j);
                int tempPlayerId = tempPlayer.getPlayer_id();

                // LOOP for all players from the client side list
                for (int n = 0; n < playerIdList.size(); n++) {
                    if (playerIdList.get(n) == tempPlayerId) {
                        ......
                    } 
                } // END loop for all players from the client side list 

                emgr.persist(tempPlayer);
                if (j == 13) {
                    System.out.println("j13, throwing exception");
                    try {
                        throw new TransactionException("sh.t happens");
                    } catch (Exception e) {
                        System.out.println("thrown and catched");

                        e.printStackTrace();
                    }
                }
            } // END loop for the player from the server side list
        } else {
            System.out.println("Seems like somebody messed up with the values.");
        }
        return squadChanged;
    }

При выбросе TransactionException я хотел бы, чтобы механизм отката работал, однако это не так, и объект сохраняется.

Ниже приведен файл persistence.xml

<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">

    <!-- CREATES DATA SOURCE -->
    <!-- <bean class="java.net.URI" id="dbUrl">
        <constructor-arg value="#{systemEnvironment['DATABASE_URL']}" />
    </bean> -->

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="url"
            value="#{ 'jdbc:postgresql://' + 'localhost' + ':' + '5432' + '/handball' }" />
        <property name="username" value="'#{ 'postgres' }" />
        <property name="password" value="#{ '........' }" />
    </bean>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="emf">
        <!-- Entities location -->
        <property name="packagesToScan" value="af.handball.entity"></property>
        <property name="dataSource" ref="dataSource" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
            </props>
        </property>

         <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        </property>  

    </bean>
</beans>

Я был бы признателен за любую информацию о том, где я мог ошибиться, спасибо!

  • 0
    Где находится конфигурация TransactionManager? :)
Теги:
spring
hibernate

1 ответ

3
Лучший ответ

Не перехватывайте исключения в транзакционном методе. Функциональность транзакций реализуется прокси-сервером, который обертывает объект службы. Исключения должны достигнуть прокси-сервера, чтобы прокси-сервер знал, что он должен откатиться. Если вы поймаете исключение в методе службы, прокси-сервер не знает, что транзакция должна была завершиться неудачей.

Удалите блок try-catch вокруг вашего исключения и дайте исключение, и вы увидите, что транзакция возвращается.

  • 0
    Большой ! Это была проблема действительно спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню