Spring data @Transactional nicht zurück Rollen

Ich entwickelt meine erste Anwendung mit Spring MVC und Spring-JPA. Ich bekomme ein problem bei Verwendung der @Transactional-annotation. Ich kommentieren einer meiner service-Methoden mit @Transactional, und ich werfe exception in der Methode, weil ich erwarte, dass es ein Rollback ausgeführt werden, aber tun Sie es nicht.

hier ist meine Konfiguration, Dateien und meine class-Dateien Inhalt:

app-context.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    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-3.0.xsd         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd   http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <context:component-scan base-package="id.co.cslgroup"/>
    <jpa:repositories base-package="id.co.cslgroup"/>

    <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <property name="testWhileIdle" value="true"/>
        <property name="timeBetweenEvictionRunsMillis" value="1800000"/>
        <property name="numTestsPerEvictionRun" value="3"/>
        <property name="minEvictableIdleTimeMillis" value="1800000"/>
        <property name="validationQuery" value="SELECT 1"/>
        <property name="defaultAutoCommit" value="false"/>
    </bean>
    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="persistenceUnitName" value="kms-pu"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter" ref="hibernateJpaAdapter"/>
    </bean>

    <bean id="customUserDetailsService" class="id.co.cslgroup.kms.svc.CustomUserDetailsService" />
    <bean id="hibernateJpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

    <context:property-placeholder location="classpath:/META-INF/database.properties"/>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/META-INF/spring/app-context.xml 
            /WEB-INF/spring/security-app-context.xml
                    /WEB-INF/spring/collection-context.xml
        </param-value>
    </context-param>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

        <!-- place constraints on a single user's ability to log in to your application -->
        <listener>
            <listener-class>
                org.springframework.security.web.session.HttpSessionEventPublisher
            </listener-class>
        </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>kmsServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>   
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>kmsServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven conversion-service="conversionService"/>

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name    ="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>



        <beans:bean id="conversionService"
            class="org.springframework.context.support.ConversionServiceFactoryBean">
          <beans:property name="converters">
              <beans:list>
                  <beans:bean class="id.co.cslgroup.kms.svc.AttributeConverter"/>
                  <beans:bean class="id.co.cslgroup.kms.svc.KeyClassConverter"/>
                  <beans:bean class="id.co.cslgroup.kms.svc.KeyTypeConverter"/>
                  <beans:bean class="id.co.cslgroup.kms.svc.KeyProfileConverter"/>
                  <beans:bean class="id.co.cslgroup.kms.svc.StringToDateConverter"/>
                  <beans:bean class="id.co.cslgroup.kms.svc.StringToIntegerConverter"/>
              </beans:list>
          </beans:property>
      </beans:bean>
    <context:component-scan base-package="id.co.cslgroup" />    
</beans:beans

>

persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="kms-pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
            <property name="hibernate.connection.charSet" value="UTF-8"/>
            <!-- Uncomment the following two properties for JBoss only -->
            <!-- property name="hibernate.validator.apply_to_ddl" value="false" /-->
            <!-- property name="hibernate.validator.autoregister_listeners" value="false" /-->
        </properties>
    </persistence-unit>
</persistence>

AttributeController.java

@Controller
@RequestMapping(value="/attribute")
public class AttributeController {

    @Autowired
    private AttributeService attService;

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@ModelAttribute("attribute") @Valid AttributeMasterForm attr,BindingResult result,Model model,@RequestParam("id") Long attID,HttpServletRequest httpRequest)
    {

        Map paramMap = httpRequest.getParameterMap();
        String[] frmTitlePar = (String[]) paramMap.get("formTitle");

        if(result.hasErrors()){
            model.addAttribute("formTitle",frmTitlePar[0]);
            model.addAttribute("id", attID);
            return "attribute/add";
        }

        System.out.println("Status: " + attr.getStatus());

        try{
            if(attr.getStatus() == null)
                attr.setStatus(false);

            if(attID != null){    
                attr = attService.edit(attr,attID);
            }
            else{
                attr = attService.save(attr);
            }
        }
        catch(Exception e){
            e.printStackTrace();
            model.addAttribute("violateMsg", "Constraint Violation");
            model.addAttribute("formTitle",frmTitlePar[0]);
            model.addAttribute("id", attr.getId());
            return "attribute/add";
        }
        return "redirect:/attribute/show?id="+attr.getId();
    }
}

AttributeRepository.java

public interface AttributeRepository extends JpaRepository<Attribute, Long> {
}

AttributeService.java

@Service
@Transactional
public class AttributeService {
@Autowired
    private AttributeRepository attributeRepository;

@Transactional(readOnly=false,propagation= Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public AttributeMasterForm save(AttributeMasterForm attForm) throws Exception{
        Attribute t = new Attribute();
        AttributeMasterForm masterForm = new AttributeMasterForm();
        //transfer value from master form to entity
        t = updateValue(t,attForm);
        //persist to database
        t = attributeRepository.save(t);

        if(t.getId() > 1){
            throw new Exception();
        }

        return this.convertToMasterForm(t);
    }

private AttributeMasterForm convertToMasterForm(Attribute attr){
            AttributeMasterForm masterForm = new AttributeMasterForm();
            masterForm.setId(attr.getId());
            masterForm.setCode(attr.getCode());
            masterForm.setName(attr.getName());
            masterForm.setStatus(attr.getStatus());

        return masterForm;
    }

private Attribute updateValue(Attribute attr,AttributeMasterForm attForm){
            attr.setCode(attForm.getCode());
            attr.setName(attForm.getName());
            attr.setStatus(attForm.getStatus());

            return attr;
        }
}

Attribute.java

package id.co.cslgroup.kms.entity;

import java.util.Collection;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;


import org.springframework.data.jpa.domain.AbstractPersistable;

@Entity
public class Attribute extends AbstractPersistable<Long> {

    @Column(nullable = false, unique = true)
    @NotEmpty
    @NotNull
    private String code;
    @Column(nullable = false)
    @NotEmpty
    @NotNull
    private String name;

    @OneToMany(fetch= FetchType.LAZY, mappedBy = "pk.attribute")
    private Collection<ProfileAttribute> profileAttribute;

    @Column(nullable = false)
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createTime;
    @Column(nullable = false)
    private String createBy;
    @Column(nullable = true)
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date updateTime;
    @Column(nullable = true)
    private String updateBy;
    @Column(nullable = false)
    private Boolean status;
    @Version
    @Column
    private Long version = 0L;

//       @ManyToMany(cascade=CascadeType.ALL)
//       @JoinTable(name = "key_attributes",
//           joinColumns = {@JoinColumn(name="attribute_id")},
//           inverseJoinColumns = {@JoinColumn(name="key_table_id")}
//       )
//       private Set<KeyTable> keytables;
//       
//       public Set<KeyTable> getKeyTables(){
//           return keytables;
//       }
//       
//       public void setKeyTables(Set<KeyTable> kt){
//           this.keytables = kt;
//       }
//       @Transient
//       private String[] testArr;
//       
//       public String[] getTestArr() {
//     return testArr;
// }
//
// public void setTestArr(String[] ta) {
//     this.testArr = ta;
// }
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getStatus() {
        return status;
    }

    public void setStatus(Boolean status) {
        this.status = status;
    }

    public String getCreateBy() {
        return createBy;
    }

    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }

    public String getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public Long getVersion() {
        return version;
    }

    @PrePersist
    private void prePersist() {
        this.createBy = "Admin";
        this.createTime = new Date();
    }

    @PreUpdate
    private void preUpdate() {
        this.updateBy = "Admin";
        this.updateTime = new Date();
    }

    /**
     * @return the keyProfiles
     */
        public Collection<ProfileAttribute> getProfileAttribute() {
        return profileAttribute;
    }

    /**
     * @param keyProfiles the keyProfiles to set
     */
    public void setProfileAttribute(Collection<ProfileAttribute> profileAttribute) {
        this.profileAttribute = profileAttribute;
    }
}

AttributeMasterForm.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package id.co.cslgroup.kms.model;

import java.util.Date;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotEmpty;

/**
 *
 * @author supriadi
 */
public class AttributeMasterForm {

    private Long id;

    @NotEmpty
    @NotNull
    private String code;

    @NotEmpty
    @NotNull
    private String name;

    private Date createTime;
    private String createBy;
    private Date updateTime;
    private String updateBy;

    private Boolean status;

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @param code the code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the status
     */
    public Boolean getStatus() {
        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(Boolean status) {
        this.status = status;
    }

    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * @return the createBy
     */
    public String getCreateBy() {
        return createBy;
    }

    /**
     * @param createBy the createBy to set
     */
    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }

    /**
     * @return the updateTime
     */
    public Date getUpdateTime() {
        return updateTime;
    }

    /**
     * @param updateTime the updateTime to set
     */
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    /**
     * @return the updateBy
     */
    public String getUpdateBy() {
        return updateBy;
    }

    /**
     * @param updateBy the updateBy to set
     */
    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }
}

In AttributeService.java im save-Methode finden Sie:

t = attributeRepository.save(t);

if(t.getId() > 1){
            throw new Exception();
        }

So, nachdem ich den Anruf sparen, habe ich sofort eine exception werfen, aber dann habe ich die Datenbank zu prüfen und es nicht zurückgesetzt.

Ich bin wirklich dankbar für jede Hilfe von Euch Jungs,
Danke!

Zeig bitte den code, wo Sie anrufen AttributeService.save() Methode
Ich rief es in AttributeController Klasse. Ich habe bearbeitet Sie meine Frage, danke.
können Sie uns zeigen, AtributeRepositoy Umsetzung? haben Sie mit der Transaktion Annotation auf Sie zu? oder so etwas wie commit drin? Ihre Berufung code sieht gut aus für mich..

InformationsquelleAutor Chrisma Andhika | 2013-05-07

Schreibe einen Kommentar