Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » EclipseLink+Spring+ComboPooledDataSource+MySQL ORM not persisting
EclipseLink+Spring+ComboPooledDataSource+MySQL ORM not persisting [message #387425] Tue, 28 April 2009 15:07 Go to next message
Bob King is currently offline Bob KingFriend
Messages: 3
Registered: July 2009
Junior Member
EclipseLink+Spring+ComboPooledDataSource+MySQL ORM not persisting

Help anybody as I have waisted over a week with this problem. Currently
considering going to Hibernate or DataNucleus(JPOX) instead of EclipseLink.

My issue is that getJpaTemplate().persist(entity) is not persisting
to database! Looking at the logs I can see that no Insert statement issued
by Eclipselink. Reviewing some of the forums (here and eclipselink), seems
to suggest transaction related issue but I can't seem to be able resolve
this.

The following is my set-up;

datasourceContext.xml

<bean id="dataSource" parent="c3poAbstractDS"
         p:driverClass="${db.driverClassName}" p:jdbcUrl="${db.url}"
         p:user="${db.username}" p:password="${db.password}" 
lazy-init="false" />

<bean id="c3poAbstractDS" class="com.mchange.v2.c3p0.ComboPooledDataSource"
         destroy-method="close" abstract="true" 
p:initialPoolSize="${db.initialPoolSize}"
         p:minPoolSize="${db.minPoolSize}" 
p:maxPoolSize="${db.maxPoolSize}"
         p:acquireIncrement="2" p:acquireRetryAttempts="30"
         p:acquireRetryDelay="100" p:checkoutTimeout="3000"
         p:maxIdleTime ="1000" p:maxIdleTimeExcessConnections="300"
         p:maxStatements="500" p:maxStatementsPerConnection ="300"
         p:maxConnectionAge="3000"
         p:idleConnectionTestPeriod="30" p:testConnectionOnCheckin="true"
         p:testConnectionOnCheckout="false"
         p:numHelperThreads="5" p:breakAfterAcquireFailure="false"
         p:autoCommitOnClose="false"
         p:forceIgnoreUnresolvedTransactions="true"
         p:usesTraditionalReflectiveProxies="false"
         p:preferredTestQuery="select 1;" />


applicationContext.xml entries:

   <!-- Generic -->
   <context:component-scan base-package="com.xxx.leopersistence" />

   <context:annotation-config />
   <aop:aspectj-autoproxy />

   <!-- Configure LoadTimeWeaver. Be sure to start JVM with 
-javaagent=spring-agent.jar -->
   <context:load-time-weaver aspectj-weaving="on" />

   <!-- JPA annotations bean post processor. Will inject persistence 
related resources. -->
   <!-- Necessary to get the entity manager injected into the factory bean 
-->
   <bean 
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" 
/>
   <!-- Adds transparent exception translation to the DAOs -->
   <bean 
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" 
/>
   <!-- Adds dependency checks for setters annotated with @Required -->
   <bean 
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" 
/>

   <bean id="jpaDialect"
         class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" 
/>
   <bean id="loadTimeWeaver"
         
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" 
/>
   <bean id="jpaVendorAdapter"
         
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"
         
p:databasePlatform="org.eclipse.persistence.platform.database.MySQLPlatform"
         p:generateDdl="false" p:showSql="true" />

<!-- classpath:META-INF/persistence.xml -->
   <bean id="entityManagerFactory"
         
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
         p:persistenceUnitName="leopersistencePU" 
p:dataSource-ref="dataSource"
         
p:persistenceXmlLocation="classpath*:/com/leofund/leopersistence/persistence.xml"
         p:jpaDialect-ref="jpaDialect" 
p:jpaVendorAdapter-ref="jpaVendorAdapter"
         p:loadTimeWeaver-ref="loadTimeWeaver" />

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

   <bean id="DBAuthorizedPositionDAO" 
class="com.leofund.leopersistence.DBAuthorizedPositionDAO"
         p:entityManagerFactory-ref="entityManagerFactory" />

   ...



persistence.xml entry;

   <persistence-unit name="leopersistencePU" 
transaction-type="RESOURCE_LOCAL">
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
      
<class>com.leofund.leopersistence.entities.DBAuthorizedPosition</class>

       ...

      <exclude-unlisted-classes>false</exclude-unlisted-classes>

      <properties>
         <property name="eclipselink.weaving" value="false" />
         <property name="eclipselink.logging.level" value="FINEST"/>
         <property name="eclipselink.target-database" value="MYSQL"/>
         <property name="eclipselink.target-server" value="None"/>
         <property name="show-sql" value="true"/>

         <property name="eclipselink.cache.shared.default" value="false"/>

         <property name="eclipselink.jdbc.read-connections.min" value="1"/>
         <property name="eclipselink.jdbc.write-connections.min" 
value="1"/>
<!--
         <property name="eclipselink.logging.logger"
                   
value="com.leofund.leoserver.utils.Log4JEclipseLinkLogger"/>

         <property name="eclipselink.cache.type.default" value="SoftWeak"/>
         <property name="eclipselink.cache.size.default" value="0"/>
 -->
         <property name="eclipselink.logging.thread" value="true"/>
         <property name="eclipselink.logging.session" value="true"/>
         <property name="eclipselink.logging.timestamp" value="true"/>
         <property name="eclipselink.logging.exceptions" value="true"/>
         <property name="eclipselink.logging.level.WEAVER" value="INFO"/>

         <property name="eclipselink.orm.throw.exceptions" value="true"/>

         <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
         <property name="eclipselink.jdbc.batch-writing.size" 
value="1000"/>
         <property name="eclipselink.jdbc.bind-parameters" value="true"/>

         <property name="eclipselink.jdbc.cache-statements" value="true"/>
         <property name="eclipselink.jdbc.cache-statements.size" 
value="10000"/>

         <property name="eclipselink.persistence-context.close-on-commit" 
value="true"/>
      </properties>
   </persistence-unit>


I have tried various combination and have scowled google to no resolve.
All my finders works fine but the insert/update/delete does not issue the
relevant SQL. Please help I am desperate as it's now eating into my
estimates big time. I have also reviewed my ID generation and tried the
various options TABLE/SEQUENCE/IDENTITY, the same result.

All my entity managers are not defined with any Transactions e.g;

public class DBEntityDAO extends JpaDaoSupport implements IDBEntityDAO {

   public void save(DBEntity entity) {
      logger.info("saving DBEntity instance");
      try {
         getJpaTemplate().persist(entity);
         logger.info("save successful");
      } catch (RuntimeException re) {
         logger.error("save failed", re);
         throw re;
      }
   }

   public void delete(DBEntity entity) {
      logger.info("deleting DBEntity instance");
      try {
         entity = getJpaTemplate().getReference(DBEntity.class,
               entity.getEntityId());
         getJpaTemplate().remove(entity);
         logger.info("delete successful");
      } catch (RuntimeException re) {
         logger.error("delete failed", re);
         throw re;
      }
   }

   public DBEntity update(DBEntity entity) {
      logger.info("updating DBEntity instance");
      try {
         DBEntity result = getJpaTemplate().merge(entity);
         logger.info("update successful");
         return result;
      } catch (RuntimeException re) {
         logger.error("update failed", re);
         throw re;
      }
   }

   public DBEntity findById(Integer id) {
      logger.info("finding DBEntity instance with id: " + id);
      try {
         DBEntity instance = getJpaTemplate().find(DBEntity.class, id);
         return instance;
      } catch (RuntimeException re) {
         logger.error("find failed", re);
         throw re;
      }
   }


I am using programmatic transactions at my service layer as follows;

   public int addJPAManager(String name, String shortName, boolean active, 
int displayOrderId)
      throws ServiceException {
      int newManagerId = -1, managerId = -1;
      TransactionStatus status = startDBTransaction();
      try {
         // find the entity represent the manager by name
         List<Object> dbEntities = 
jpaDelegateServices.findByProperty(DBEntity.class, "name", name);
         DBEntity dbEntity = null;
         if (dbEntities == null || dbEntities.size() == 0) {
            // none exists then create new
            dbEntity = new DBEntity(name, shortName, 
SimpleUtils.booleanString(active));
            jpaDelegateServices.save(DBEntity.class, dbEntity);
         } else {
            if (dbEntities.size() > 1)
               throw new ServiceException("Error, non unique entity exists 
for the new manager!");
            dbEntity = (DBEntity)dbEntities.get(0);
         }
         managerId = dbEntity.getEntityId();

         // find the manager by managerId
         DBManager dbManager = 
(DBManager)jpaDelegateServices.findById(DBManager.class, managerId);
         if (dbManager != null)
            throw new ServiceException("Error, new manager already 
exists!");

         dbManager = new DBManager(managerId, dbEntity, 
(short)displayOrderId, booleanString(active));
         jpaDelegateServices.save(DBManager.class, dbManager);
         newManagerId = dbManager.getManagerId();

         transactionManager.commit(status);
         messagingServices.broadcastDataElementChanged("Manager", 
newManagerId);
      } finally {
         if (!status.isCompleted()) transactionManager.rollback(status);
      }
      return newManagerId;
   }

   private TransactionStatus startDBTransaction() {
      DefaultTransactionDefinition def = new 
DefaultTransactionDefinition();
      
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
      return transactionManager.getTransaction(def);
   }
Re: EclipseLink+Spring+ComboPooledDataSource+MySQL ORM not persisting [message #387431 is a reply to message #387425] Wed, 29 April 2009 12:53 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

My guess would be that you are not beginning or committing a JPA
transaction. You seem to be wrapping all of the JPA access in your own
classes, please include this code and your log.

Ensure you do a,

entityManager.getTransaction().begin();

and a,

entityManager.getTransaction().commit();

You may also wish to try calling entityManager.flush().

If you are trying to integrate with Spring's transaction services, then it
may be a configuration issue.

---
James
http://www.nabble.com/EclipseLink---Users-f26658.html


James : Wiki : Book : Blog : Twitter
Re: EclipseLink+Spring+ComboPooledDataSource+MySQL ORM not persisting [message #387437 is a reply to message #387431] Wed, 29 April 2009 13:42 Go to previous message
Bob King is currently offline Bob KingFriend
Messages: 3
Registered: July 2009
Junior Member
Just a clarification, I am so new to these but I have used Hibernate
before. We have over 90 entities and I am using a Delegate class (using
Reflection) to access the DAO classes as follows;

------------------------------------------------------------ ------------------

public class JPADelegateServicesImpl
implements ApplicationContextAware, JPADelegateServices,
InitializingBean {

// The logger
private static final Log
logger = LogFactory.getLog(JPADelegateServicesImpl.class);

private ApplicationContext ctx = null;

public JPADelegateServicesImpl() { }

public void afterPropertiesSet() {
logger.info("Initializing [JPADelegateServicesImpl] bean...");
}

public Boolean isExists(Class<?> clazz, Object id) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "isExists");

return (Boolean)method.invoke(object, new Object[] { id });
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

public Object findById(Class<?> clazz, Object id) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "findById");

Object retObject = method.invoke(object, new Object[] { id });
return retObject;
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

@SuppressWarnings("unchecked")
public List<Object> findAll(Class<?> clazz, int...rowStartIdxAndCount)
throws LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "findAll");

Object listObject = method.invoke(object, new Object[] {
rowStartIdxAndCount });
return (List<Object>)listObject;
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

@SuppressWarnings("unchecked")
public List<Object> findByProperty(Class<?> clazz, String propertyName,
Object value,
int...rowStartIdxAndCount) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "findByProperty");

Object listObject =
method.invoke(object, new Object[] { propertyName, value,
rowStartIdxAndCount });
return (List<Object>)listObject;
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

public void save(Class<?> clazz, Object entity) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "save");

method.invoke(object, new Object[] { entity });
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

public void delete(Class<?> clazz, Object entity) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "delete");

method.invoke(object, new Object[] { entity });
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

public void update(Class<?> clazz, Object entity) throws
LeoServerRemoteException {
try {
Object object = getDAOSpringBean(clazz);
Method method = findMethod(object.getClass(), "update");

method.invoke(object, new Object[] { entity });
} catch (IllegalAccessException iae) {
throw new LeoServerRemoteException(iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
// Lets see the exception stack and check what has caused this
exception
Throwable myThrowable = ite;
while (true) {
if (myThrowable.getCause() != null)
myThrowable = myThrowable.getCause();
else
break;
}
logger.error(myThrowable.getMessage(), myThrowable);
throw new LeoServerRemoteException(myThrowable.getMessage(),
myThrowable);
} catch (Exception e) {
throw new LeoServerRemoteException(e.getMessage(), e);
}
}

private Object getDAOSpringBean(Class<?> clazz) {
String className = clazz.getSimpleName() + "DAO";
Object object = ctx.getBean(className);
return object;
}

@SuppressWarnings("unused")
private Class<?> loadClass(String className) throws
ClassNotFoundException {
Class<?> theClass = null;
try {
theClass =
Thread.currentThread().getContextClassLoader().loadClass(cla ssName);
}
catch (ClassNotFoundException e) {
theClass = Class.forName(className);
}
return theClass;
}

private Method findMethod(Class<?> clazz, String methodName) throws
NoSuchMethodException {
Method[] methods = clazz.getMethods();
Method method = null;
boolean methodFound = false;

for (int i = 0; i < methods.length; i++)
if (methods[i].getName().equals(methodName)) {
methodFound = true;
method = methods[i];
break;
}

if (!methodFound)
throw new NoSuchMethodException
("The method " + methodName + "(...) was not found in class " +
clazz.getCanonicalName());

return method;
}

@Override
public void setApplicationContext(ApplicationContext ctx) throws
BeansException {
this.ctx = ctx;
}
}

------------------------------------------------------------ ------------------

With these class I don't need to expose the DAOs to the client. My main
issue is the configuration of Spring and/or Eclipselink to wrap DAO calls
in a transaction. All my finders seems to work fine. The log is quite huge
but I can see that there are no INSERT statements issued.

Incidentally, we don't use declarative transactions as we call some of the
service layers within and spring does not support it.

Thanks in advance
Previous Topic:2 same queries => different results?
Next Topic:Problem while executing the stored procedure
Goto Forum:
  


Current Time: Fri Jan 24 11:15:08 GMT 2025

Powered by FUDForum. Page generated in 0.03049 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top