• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Devaka Cooray
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Jj Roberts
  • Al Hobbs
  • Piet Souris

Transaction management in Spring

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All ,

I'm developing an application that is based on Spring MVC + mySQL.

I'm trying to use Spring's transaction management but for some reason the transaction is never being rolled back.

Can you please assist?

I have this service bean:
@Transactional(rollbackFor={Exception.class,RuntimeException.class}, propagation=Propagation.REQUIRED)
@Repository
public abstract class AbstractDbFacade<T> {
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this. entityManager = entityManager;
}

public T insert( T entity )
{
getEntityManager().persist( entity );
throw new RunTimeException();//for some reason throwing this exception is not //causing roll back
}
}

Configuration files:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/<value>" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

<bean id="entityManagerFactory" lazy-init="true"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="<unit name>"
p:jpaVendorAdapter-ref="jpaVendorAdapter"
p:jpaDialect-ref="jpaDialect"
p:dataSource-ref="dataSource"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>

<!-- being used just for one bean that is based on it -->
<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory" />



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

<context:component-scan base-package="<base package>" />
</beans>


persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="value" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>some entity classes</class>
<properties>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/<value>"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
</properties>
</persistence-unit>
</persistence>


Thanks in advanced.
 
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) You need to post the code that is running that you say is not rolling back. So why do you even think it should rollback.

Also you post that you ahve

@Transactional(rollbackFor={Exception.class,RuntimeException.class}, propagation=Propagation.REQUIRED)

Why not just @Transactional, especially since with just @Transactional, the default propagation is REQUIRED and to rollback for any RuntimeException.

Mark
 
orel shai
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mark,


This is the original code:

@Transactional(rollbackFor={Exception.class,RuntimeException.class}, propagation=Propagation.REQUIRED)
@Repository
public abstract class AbstractDbFacade<T> {
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this. entityManager = entityManager;
}

public T insert( T entity )
{
getEntityManager().persist( entity );
return entity;
}
}



@Repository
public class UserDbFacade extends AbstractDbFacade<User>{

public UserDbFacade()
{
super(User.class);
}
}


@Service
@Transactional(rollbackFor={Exception.class,RuntimeException.class} , propagation=Propagation.REQUIRED)
public class UserManagementBean{

@Autowired
protected UserDbFacade userFacade;

public User createUser(UserDTO user) {
userFacade.insert(user.dtoToEntity());
throw new RuntimeException();
}
}

@Entity
public class User{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;

@Column(name="USER_NAME")
private String userName;

@Column(name="PASSWORD")
private String password;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

public String getUserName() {
return userName;
}
public void setUserName(String name) {
this.userName = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return new StringBuilder(512).append(" id:").append(id).append(" name:").append(userName).append(" password:").append(password).toString();
}

@Override
public boolean equals(Object obj){
if ( (obj == null) || !(obj instanceof User) ) {
return false;
}
User other = (User)obj;
return id.equals(other.getId());

}
@Override
public int hashCode(){
int hashCode = 17;
hashCode = 37 * hashCode + id.hashCode();
return hashCode;

}
}

CREATE TABLE USER
(
ID BIGINT PRIMARY KEY AUTO_INCREMENT ,
USER_NAME VARCHAR(256) NOT NULL,
PASSWORD VARCHAR(256) NOT NULL
);

Regarding the annotation issue , originally I've just marked the class with @Transactional and no other properties.

I think that the issue is not code related but something in the configuration files.

Thanks
 
Mark Spritzler
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry. We have a way to post code that keeps its formatting. Please use it, The way that you just copy and paste makes it all unindented and tough to read.

Mark
 
Mark Spritzler
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) It doesn't look like anything wrong in the configuration
2) Just use @Transactional.
3) Your class doesn't implement an interface. Spring makes Proxies and adds the Transaction code via interfaces. So if you class doesn't implement an interface a proxy can't be created. You would need to have CGLIB in your classpath and tell Spring in your configuration to create Proxies based on CGLIB.

The best way is to make interfaces for your classes.

What does your log look like when this code is run?

If you do debugging through the code. When you set a break point in the line that calls your UserManagementBean, in the variables box, what type of class shows. Does it show Proxy or UserManagementBean. If it shows UserManagementBean, then that means you are not getting Spring's transaction management into that class. See interface statement from above.

Mark
 
orel shai
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mark ,

Thanks for all the help!

The issue was in the data base side , apparently if you're using Mysql and you want to support transactions then you need to use InnoDB.
 
Mark Spritzler
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

orel shai wrote:Hi Mark ,

Thanks for all the help!

The issue was in the data base side , apparently if you're using Mysql and you want to support transactions then you need to use InnoDB.



Glad you got it resolved.

Mark
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic