Why is my transaction rolled back unexpectedly? - java

In our project, we are trying to get code that is currently deployed on WebSphere working on Liberty instead.
After receiving a message an MDB calls a method in a service which inserts the data into a DB2 database.
The problem is that when flush is called, we get the following errors in the log:
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1136) ~[hibernate-entitymanager-5.1.3.Final.jar:5.1.3.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1297) ~[hibernate-entitymanager-5.1.3.Final.jar:5.1.3.Final]
[ERROR ] WLTC0017E: Resources rolled back due to setRollbackOnly() being called.
There are no other errors, like SQL query not being correct or something like that.
Since this code is working fine in WebSphere, I'm wondering if there is something wrong in the configuration or if Liberty does something different in handling transactions.
Below are the relevant pieces of code and configuration:
#Service
public class IdentificationService implements IIdentificationService {
#Autowired
private IIdentificationDAO identificationDAO;
#Transactional
public Identification insertIdentificationData(RequestForIdentificationRequest request, String referenceNumber) {
final Identification identification = new Identification();
...
identificationDAO.create(identification);
LOGGER.debug("Identification record saved with id: {}", identification.getId());
return identification;
}
}
#Repository
public class IdentificationDAO extends BaseDAO implements IIdentificationDAO {
#Override
public void create(final Identification identification) {
insertRecord(identification);
}
}
public abstract class BaseDAO
{
#PersistenceContext(name = "UserData", unitName = "UserData")
private EntityManager em;
/**
* #param record
*/
public <T> void insertRecord(final T record)
{
em.persist(record);
em.flush();
}
}
public class Identification implements Serializable {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(sequenceName = "IDENTIFICATION_SEQ", name = "sequenceGenerator", allocationSize = 1)
private Long id;
...
}
applicationContext.xml
<jee:jndi-lookup id="userDataSource" jndi-name="jdbc/userdataDB" />
<bean id="userDataEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="UserData" />
<property name="persistenceXmlLocation" value="classpath:persistence-userdata.xml" />
<property name="dataSource" ref="userDataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.DB2Dialect" />
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="userDataEntityManagerFactory" />
</bean>
server.xml
<library id="DB2JCCLib">
<fileset dir="/etc/liberty/jdbc" includes="db2jcc4.jar, db2jcc_license_cisuz.jar, db2jcc_license_cu.jar"/>
</library>
<dataSource id="UserDB" jndiName="jdbc/userdataDB" type="javax.sql.XADataSource"
isolationLevel="TRANSACTION_READ_COMMITTED">
<jdbcDriver libraryRef="DB2JCCLib" javax.sql.XADataSource="com.ibm.db2.jcc.DB2XADataSource"/>
<properties.db2.jcc serverName="${datasource.userdb.serverName}" portNumber="${datasource.userdb.portNumber}"
databaseName="${datasource.userdb.databaseName}"
user="user" password="password"/>
</dataSource>
UPDATE: The problem turned out to be multiple transaction manager beans (named the same) in the configuration pointing at different databases.
Giving them unique names and referring to them explicitly in the Transactional annotation did the trick

Related

Spring JPA Hibernate handle large databases

I am new to JPA, Hibernate as well as Spring. Currently I am creating a spring web service which work with a database with a large number of tables. To access those tables I have created separate class annotating #Entity. Then I created a generic DAO class as all my entities need similar operations.
#Transactional
public class GenericJpaDao<T, ID extends Serializable> {
private Class<T> persistentClass;
private EntityManager entityManager;
public GenericJpaDao(Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
protected EntityManager getEntityManager() {
return entityManager;
}
#PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public Class<T> getPersistentClass() {
return persistentClass;
}
#Transactional(readOnly = true)
public T findById(ID id) {
T entity = (T) getEntityManager().find(getPersistentClass(), id);
return entity;
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
public List<T> findAll() {
return getEntityManager().createQuery("select x from " + getPersistentClass().getSimpleName() + " x").getResultList();
}
public T save(T entity) {
getEntityManager().persist(entity);
return entity;
}
public T update(T entity) {
T mergedEntity = getEntityManager().merge(entity);
return mergedEntity;
}
public void delete(T entity) {
entity = getEntityManager().merge(entity);
getEntityManager().remove(entity);
}
public void flush() {
getEntityManager().flush();
}
}
Now I tried to instantiate this GenericJpaDao in the code with relevant Entitiy Class as the persistentClass. But then I could not find a way to set the entitiyManager as I am configuring it via datasource-config.xml as
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="hibernatePersistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
So according to what I understood from the samples available I need to create separate DAO classes for all my entity classes and instantiate them in spring-ws-servlet.xml.
<bean id="testDao" class="com.sample.dao.TestDao" />
<bean id="service"
class="com.sample.service.DefaultService">
<property name="testDao" ref="testDao" />
</bean>
I think this will be a problem in the long run as I need to have two separated classes for each table in the database, instaintiating them in the xml, keep track of all of them at my service class. Is there any method to overcome this or any best practice available?
You wont need to create a specific DAO for each of your classes.
But you will have to remove the constructor and change your method signatures to include the needed persistentClass (or an instance where you call getClass on).
Basically you need to remove the persistentClass property and change the methods to use the class dynamically from the generic parameter of type T or Class.
That way you have ONE spring managed DAO which is able to handle all of your entities.

Why can't I retrieve the entities I've just persisted?

I've got this web service that basically queries the database and returns all persisted entities. For testing purposes, I've created a TestDataManager that persists 2 example entities after Spring context is loaded (BTW, I'm using JAX-WS, Spring, Hibernate and HSQLDB).
My TestDataManager looks like this:
#Component
public class TestDataManager {
#Resource
private SessionFactory sf;
#PostConstruct
#Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void insertTestData(){
sf.openSession();
sf.openSession().beginTransaction();
sf.openSession().persist(new Site("site one"));
sf.openSession().persist(new Site("site two"));
sf.openSession().flush();
}
}
My JAX-WS endpoint looks like this:
#WebService
public class SmartBrickEndpoint {
#Resource
private WebServiceContext context;
public Set<Site> getSitesForUser(String user){
return getSiteService().findByUser(new User(user));
}
private ISiteService getSiteService(){
ServletContext servletContext = (ServletContext) context.getMessageContext().get("javax.xml.ws.servlet.context");
return (ISiteService) BeanRetriever.getBean(servletContext, ISiteService.class);
}
}
This my Service class:
#Component
#Transactional(readOnly = true)
public class SiteService implements ISiteService {
#Resource
private ISiteDao siteDao;
#Override
public Set<Site> findByUser(User user) {
return siteDao.findByUser(user);
}
}
This is my DAO:
#Component
#Transactional(readOnly = true)
public class SiteDao implements ISiteDao {
#Resource
private SessionFactory sessionFactory;
#Override
public Set<Site> findByUser(User user) {
Set<Site> sites = new LinkedHashSet<Site>(sessionFactory.getCurrentSession().createCriteria(Site.class).list());
return sites;
}
}
This is my applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="br.unirio.wsimxp.dao"/>
<context:component-scan base-package="br.unirio.wsimxp.service"/>
<context:component-scan base-package="br.unirio.wsimxp.spring"/>
<bean id="applicationDS" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:file:sites"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="applicationDS" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>
<!--<prop key="hibernate.current_session_context_class">thread</prop>-->
<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
This is what's going on now:
when the app is deployed, TestDataManager#insertTestData kicks-in (due to #PostConstruct) and persist does not raise any exception. I should have 2 entities in the DB by now.
Afterwards, I invoke the endpoint by a SOAP client, and the request goes all the way up to the DAO. The Hibernate invocation does not raise any exception, but the returned list is empty.
The odd thing is, in TestDataManager, if I switch from sf.openSession() to sf.getCurrentSession(), I get an error message: "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here".
What I am doing wrong here? Why is the query "not seeing" the persisted entities? Why do I need to invoke sf.openSession() on TestDataManager although it's annotated with #Transactional?
I have done some tests with hibernate.current_session_context_class=thread in application.xml, but then I just switch problems in each class. I'd like not needing to manually invoke sf.openSession() and leave that for Hibernate to take care.
Thanks a lot for any help!
I think you need to commit the transaction on insertTestData:
#PostConstruct
#Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void insertTestData(){
Session session = sf.openSession();
session.persist(new Site("site one"));
session.persist(new Site("site two"));
session.flush();
session.close();
}
(I use hibernate in jpa mode)
I think your transactional annotations are not intercepted properly. Have you specified the HibernateVendorAdapter? In jpa+hibernate the integration is not fully setuped without it! Most likely you are missing this declaration.
After you should be able to autowire directly the Session instead of the Factory.
As a side note. If you use opensession in your code at least call it only once and keep the session in a variable. Else you are always opening a new one on each call i believe.
#PostConstruct
public void insertTestData(){
Obejct o = new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
//Your code here
}
});
}
source: http://forum.springsource.org/showthread.php?58337-No-transaction-in-transactional-service-called-from-PostConstruct&p=194863#post194863

Is Exception handling required in Spring Transaction?

I am having a doubt in exception handling with a Transaction. To state clearly my problem I would like to show my configuration:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionInterceptor" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
</property>
</bean>
<bean id="baseService" abstract="true">
<property name="daoProvider" ref="daoProvider" />
</bean>
<bean id="customerService" parent="transactionInterceptor">
<property name="target">
<bean class="com.edfx.adb.service.CustomerService" parent="baseService" />
</property>
</bean>
<bean id="daoProvider" class="com.edfx.adb.dao.provider.DaoProvider">
<property name="customerDao" ref="customerDao" />
</bean>
<bean id="customerDao" class="com.edfx.adb.dao.CustomerDao">
<constructor-arg value="#{T(com.edfx.adb.persist.entity.Customer)}" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
The active transaction class is:
#Transactional
public class CustomerService extends BaseService implements ICustomerService {
#Transactional(readOnly = true)
public Customer getCustomerById(String id) {
return getDaoProvider().getCustomerDao().getCustomerById(id);
}
#Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class })
public void addNewCustomer(CustomerDTO customerDTO) {
Customer customer = new Customer();
customer.setCustomerId(customerDTO.getCustomerId());
customer.setCustomerName(customerDTO.getCustomerName());
customer.setActive(customerDTO.isActive());
getDaoProvider().getCustomerDao().save(customer);
}
}
My doubts lies in the method addNewCustomer. I have set rollbackFor = { Throwable.class }.
How does it work?
Also do I need to explicitly handle exception like:
#Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class })
public boolean addNewCustomer(CustomerDTO customerDTO) {
Customer customer = new Customer();
customer.setCustomerId(customerDTO.getCustomerId());
customer.setCustomerName(customerDTO.getCustomerName());
customer.setActive(customerDTO.isActive());
try {
getDaoProvider().getCustomerDao().save(customer);
} catch (Throwable throwable) {
return false;
}
return true;
}
Forcefully I have created an exception by deleting a column from the customer table, BUT that exception wasn't catch in the try-catch block, rather I can catch that exception from the managed bean where I have invoked the addNewCustomer method.
This is an excerpt from Spring docs
In its default configuration, the Spring Framework's transaction
infrastructure code only marks a transaction for rollback in the case
of runtime, unchecked exceptions; that is, when the thrown exception
is an instance or subclass of RuntimeException. (Errors will also - by
default - result in a rollback). Checked exceptions that are thrown
from a transactional method do not result in rollback in the default
configuration.
You set rollbackFor = Throwable.class, now Spring will rollback for any Exception / Error. By default, whether we like it or not, Spring will rollback only for RuintimeException, and commit otherwise
The Spring framework only throws RuntimeExceptions, technically you never have to catch any exceptions.

EntityManager persist() not saving anything to database

My entityManager persist() gets id from sequence and puts it to my Image object but the Image object itself is not showing up in the database. EntityManager.flush() gives an error so I can't commit this way. Here is my code.
#Repository
public class ImageDaoImpl extends BaseDao implements ImageDao {
#PersistenceContext
protected EntityManager entityManager;
#Override
#Transactional
public void create(Image image) {
JpaTemplate jpaTemplate = getJpaTemplate(entityManager);
jpaTemplate.persist(image);
}
#Repository
public class BaseDao {
private JpaTemplate jpaTemplate;
public JpaTemplate getJpaTemplate(EntityManager entityManager){
if(jpaTemplate == null)
jpaTemplate = new JpaTemplate(entityManager);
return jpaTemplate;
}
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
</property>
<property name="persistenceUnitName" value="sample"></property>
</bean>
<!-- DataSource Setup -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/imageCapture" />
<property name="username" value="myusername" />
<property name="password" value="mypassword" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
This generally happens when Transaction in not applied.. I doubt #Transactional interceptor is not intercepting properly.
persist() means "add object to list of managed entries". To save object to data base you must call flush() method. But remember you must call in inside the transaction.
//Edit:
Example save method.
public void save(T t){
// begin transaction
em.getTransaction().begin();
if (!em.contains(t)) {
// persist object - add to entity manager
em.persist(t);
// flush em - save to DB
em.flush();
}
// commit transaction at all
em.getTransaction().commit();
}
This is not the best that you can make, but good enough.
Check your server logs. Are you creating new EntityManger? and have not begun the transaction. I think, Where you have begun that is another EntityManager object.
Check EntityManager object is not getting created twice. In my case I was initialize EntityManager object in one method and mistakenly calling that method twice during opening transaction and persisting data.
Incorrect code:
EntityTrasaction transaction = getEntityManager().getTransaction().begin();
getEntityManager().persist(customer); // This line is calling another object of EntityManager
transaction.commit();
Correct code:
EntityManager em = getEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(customer);
transaction.commit();
public EntityManager getEntityManager(){
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("punit");
return entityManagerFactory.createEntityManager();
}
Check your mvc-dispatcher-servlet.xml . Here in <context:component-scan base-package="pass"/> pass should equal to package where your controllers are
I faced this problem in when running test cases with SpringJUnit4ClassRunner
I solved it by
wrapping the test function with
#Autowired
private PlatformTransactionManager transactionManager;
// in your test funciton
// Declare a transaction programmatically to be able to rollback.
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try {
// here test of Dao goes
} finally {
transactionManager.rollback(transaction);
}
hope this helps you

Transactions not working unless inside DAO

I have a problem with transactions in that annotating a service that calls a DAO with #Transactional throws an exception stating that the Session is not open. The only way I can get it working is by annotating the DAO with #Transactional. What on earth can be happening?
This is what I'd like to do but doesn't work:
class CustomerService {
private CustomerDao dao;
#Transactional
public void foo() {
int customerId = dao.getCustomer("fred");
}
}
class CustomerDao {
private HibernateTemplate hibernateTemplate;
public int getCustomer(String name) {
String sql = "SELECT {m.*} from Customers {m} where name=:name";
Query qry = getSession().createSQLQuery(sql).addEntity("m", Customer.class);
qry.setParameter("name", name);
qry.setCacheable(false);
List<Customer> list = qry.list();
return list.iterator().next().getId();
}
private Session getSession() {
return hibernateTemplate.getSessionFactory().getCurrentSession();
}
}
This is what I'm doing instead but would rather not have to:
class CustomerService {
private CustomerDao dao;
public Customer(CustomerDao dao) {
this.dao = dao;
}
public void foo() {
int customerId = dao.getCustomer("fred");
}
}
class CustomerDao {
private HibernateTemplate hibernateTemplate;
#Transactional
public int getCustomer(String name) {
String sql = "SELECT {m.*} from Customers {m} where name=:name";
Query qry = getSession().createSQLQuery(sql).addEntity("m", Customer.class);
qry.setParameter("name", name);
qry.setCacheable(false);
List<Customer> list = qry.list();
return list.iterator().next().getId();
}
private Session getSession() {
return hibernateTemplate.getSessionFactory().getCurrentSession();
}
}
The problem seems to be caused by the CustomerService being instantiated inside the constructor of a wrapper class, where the wrapper is declared in the Spring xml context file:
class AllServices {
private final CustomerService customerService;
private final OrderService orderService;
#Autowired
public AllServices(CustomerDao customerDao, OrderDao orderDao) {
this.customerService = new CustomerService(customerDao);
this.orderService = new OrderService(orderDao);
}
public CustomerService getCustomerService() {
return this.customerService;
}
public OrderService getOrderService() {
return this.orderService;
}
}
The spring file looks like this:
<context:annotation-config />
<import resource="classpath:db-spring-conf.xml"/>
<bean id="allServices" class="myPackage.AllServices" />
and the db-spring-conf:
<bean id="editorDatasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${versioning.db}" />
<property name="username" value="${versioning.user}" />
<property name="password" value="${versioning.pass}" />
</bean>
<tx:annotation-driven transaction-manager="editorTransactionManager"/>
<bean id="editorSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="editorDatasource"/>
<property name="exposeTransactionAwareSessionFactory">
<value>true</value>
</property>
<property name="annotatedClasses">
<list>
<value>myPackage.Order</value>
</list>
</property>
<property name="mappingResources">
<list>
<value>mappings/customer.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!-- Enable Query Cache -->
<prop key="hibernate.cache.use_query_cache">false</prop>
<!-- Enable 2nd Level Cache -->
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean id="editorHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="editorSessionFactory"/>
</bean>
<bean id="editorTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="editorSessionFactory" />
</bean>
<!-- DAOs -->
<bean id="customerDao" class="myPackage.CustomerHibernateDao" />
<bean id="orderDao" class="myPackage.OrderHibernateDao" />
I've now moved the instantiation of CustomerService up to the Spring config file and everything works a treat. Do all classes using #Transactional have to be in the context file? Also in order to make it work I had to create an interface for CustomerService to prevent an exception whilst loading the context file - Could not generate CGLIB subclass of class
So, you identified the cause of problem - Spring's #Transactional support is an aspect, and aspects in Spring are applied only to the components managed by the Spring contrainer (though it can be changed, but it's an advanced feature for complex cases).
If you don't like declaring services in XML, you may take a look at other options to delcare Spring-managed components:
Classpath scanning
Java-based configuration (since Spring 3.x)
Regarding the problem with CGLIB proxies see 7.6 Proxying mechanisms - probably you don't have CGLIB implementation in the classpath.

Categories