Spring, eclipselink, compass integration - spring

I went through several articles and configured the following, but i can see some problems with transaction management. Please let me know whether i'm using compass correctly in the below configurations:
in Spring-config:
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean class="org.compass.spring.support.CompassContextBeanPostProcessor"/>
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="classMappings">
<list>
<value>......</value>
<value>......</value>
<value>......</value>
</list>
</property>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">file:///usr/local/lucene</prop>
<prop key="compass.transaction.factory">
org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager"/>
</bean>
in compass code:
private CompassSession session;
#CompassContext
protected void setCompassSession(CompassSession session) {
this.session = session;
}
public void index(Coupon coupon) throws AppException{
try {
session.save(coupon);
} catch (CompassException exception) {
logger.debug("Error in coupon indexing: "+ exception.getMessage());
}
}
in Service Layer:
#Transactional
public void saveCoupon(Coupon coupon) throws AppException{
Coupon savedCoupon = dbCouponDAO.saveCoupon(coupon); // saves to db through eclipselink
nonDbCouponDAO.index(savedCoupon); // indexes in compass
}
As per my understanding, transaction manager configured to eclipselink in spring can be used as compass transaction manager too, and both eclipselink and compass operations can be used in a single unit as i have mentioned in service layer.
Please let me know if i'm doing anything wrong here.
Thanks.

Try to add this,
<!-- Search Manager using Comass abstractions. -->
<bean class="org.compass.spring.support.CompassContextBeanPostProcessor"/>
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">file://${user.home}/indexes</prop>
<prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
</props>
</property>
<property name="classMappings">
<list>
<value>MyEntity</value>
</list>
</property>
<property name="transactionManager">
<ref local="transactionManager" />
</property>
</bean>
<bean id="jpaGpsDevice" class="org.compass.gps.device.jpa.JpaGpsDevice">
<property name="name">
<value>jpaDevice</value>
</property>
<property name="entityManagerFactory">
<ref local="entityManagerFactory" />
</property>
<property name="nativeExtractor">
<bean class="org.compass.gps.device.jpa.extractor.SpringNativeJpaExtractor" />
</property>
</bean>
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
<property name="compass">
<ref bean="compass" />
</property>
<property name="gpsDevices">
<list>
<ref bean="jpaGpsDevice" />
</list>
</property>
</bean>
<!-- COMPASS END -->
Let me know if this helps.

Related

Manage Hibernate and Activiti with Common TransactionManager

I want to use a common transaction manager (JpaTransactionManager) for hibernate and activiti, but i can not! And i have read all internet resources for that! Hear is a simple scenario (which does not even use hibernate!!):
Save variables in task
Save variable in task#execution
Complete task
Scenario implementation (in a spring bean method with #Transactional annotation):
#Component
public class TaskManager {
#Autowired TaskService taskService;
#Autowired RuntimeService runtimeService;
#Transactional
public void completeTask(CompleteTaskRequest request) {
Task task = taskService.createTaskQuery().taskId(request.getTaskId()).singleResult();
if (task == null) {
throw new ActivitiObjectNotFoundException("No task found");
}
taskService.setVariableLocal(task.getId(), "actionDisplayUrl", request.getActionDisplayUrl());
taskService.setVariableLocal(task.getId(), "actionSummaryUrl", request.getActionSummaryUrl());
runtimeService.setVariableLocal(task.getExecutionId(), "prevTaskId", task.getId());
taskService.complete(task.getId());
}
}
It's obvious: if taskService.complete throws error, the whole transaction should be rollbacked, so all saved variables should be rollbacked, and the below test case should be passed:
#Test
#Deployment(resources = "org.activiti.test/CompleteTaskTest.bpmn20.xml")
public void testCompleteTaskWithError() {
Map<String, Object> processVars = new HashMap<>();
processVars.put("error", true); // Causes throwing error in ScriptTaskListener
runtimeService.startProcessInstanceByKey("CompleteTaskTest", processVars);
Task task = taskService.createTaskQuery().taskName("Task 1").singleResult();
CompleteTaskRequest req = new CompleteTaskRequest();
req.setTaskId(task.getId());
req.setActionDisplayUrl("/actions/1234");
req.setActionSummaryUrl("/actions/1234/summary");
try {
taskManager.completeTask(req);
fail("An error expected!");
} catch(Exception e) {
}
// Check variables rollback
assertNull(taskService.getVariableLocal(task.getId(),"actionSummaryUrl"));
assertNull(taskService.getVariableLocal(task.getId(),"actionDisplayUrl"));
assertNull(runtimeService.getVariableLocal(task.getExecutionId(), "prevTaskId"));
}
But it fails, the variables are committed to DB (not rollbacked).
Spring context (Using org.springframework.orm.jpa.JpaTransactionManager as transaction manager):
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="idGenerator" ref="idGenerator"/>
<property name="databaseSchemaUpdate" value="true" />
<property name="jpaEntityManagerFactory" ref="entityManagerFactory" />
<property name="jpaHandleTransaction" value="true" />
<property name="jpaCloseEntityManager" value="true" />
<property name="beans" ref="processEngineBeans" />
<property name="jobExecutorActivate" value="false" />
<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="true" />
</bean>
<aop:config proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="processEngineBeans" class="java.util.HashMap">
<constructor-arg index="0" type="java.util.Map">
<map>
</map>
</constructor-arg>
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="idGenerator" class="org.activiti.engine.impl.persistence.StrongUuidGenerator" />
<bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule">
<property name="processEngine" ref="processEngine" />
</bean>
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="packagesToScan" value="org.activiti.test" />
<property name="defaultDataSource" ref="dataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect_resolvers">org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" >
<property name="proxyTargetClass" value="true" />
</bean>
Versions:
Activiti version: 5.22.0
DB: h2 (Also tested with Oracle in production)
What is wrong with my configurations?
P.S.
The test project is uploaded here.
I have also asked this question in alfresco forum.
UPDATE::
By using org.springframework.jdbc.datasource.DataSourceTransactionManager instead of org.springframework.orm.jpa.JpaTransactionManager the test case passed. But now i can not persist JPA entities.
The problem is solved by resolving conflict between MyBatis (JDBC) and Hibernate (JPA):
jpaVendorAdapter property should be added to entityManagerFactory bean:
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
So entityManagerFactory bean should be like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect_resolvers">org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
For more details see answer of this question.

Spring session factory is always null for multiple datasources

I am trying to #Autowire multiple Hibernate SessionFactory inside my application through Spring 4 SessionFactory DI. Only one Datasource(epi) is getting injected properly but the other two Datasources SessionFactory values are always null.
Two of them are oracle database and the other one is DB2. I am not sure what I am doing wrong.
Here is my spring-Datasource.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="epiStageDS"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver"/>
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
<bean id="epi"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
<bean id="eveDS"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
<!-- Session factory for EPI db -->
<bean id="episessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="epi" />
<property name="packagesToScan">
<list>
<value>edu.eve.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
</props>
</property>
</bean>
<!-- EVE DS SESSION FACTORY -->
<bean id="eveSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="eveDS" />
<property name="packagesToScan">
<list>
<value>edu.eve.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
</props>
</property>
</bean>
<!-- Session factory for Stage DS db -->
<bean id="stageDsSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="epiStageDS" />
<property name="packagesToScan">
<list>
<value>edu.eve.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.show_sql">${hibernate.db2.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.db2.format_sql:false}</prop>
</props>
</property>
</bean>
<bean id="epiTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="episessionFactory" />
</bean>
<bean id="eveTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="eveSessionFactory" />
</bean>
<bean id="stageDsTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="stageDsSessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Here are the classes in which I am autowiring SessionFactory.
Below sessionFactory is getting injected perfectly.
#Transactional("epiTransactionManager")
public class EpiBaseService {
#Autowired
#Qualifier("episessionFactory")
private SessionFactory sessionFactory;
Autowired sessionFactory value are always null for below DS.
#Transactional("stageDsTransactionManager")
public class StageDsBaseService {
#Autowired
#Qualifier("stageDsSessionFactory")
private SessionFactory sessionFactory;
#Transactional("eveTransactionManager")
public class EveBaseService {
#Autowired
#Qualifier("eveSessionFactory")
private SessionFactory sessionFactory;
Please tell me what i am missing here.
I know what I was doing wrong. I was creating a new object of service class rather than #Autowiring inside the spring controller. I was doing this in order to make sure that my sessionfactory is not null but looks like that's not the correct way to do it. You have to use the Spring IOC container to inject the service class in your controller. Now all the sessionFactories are properly connected to specified datasources.

java.sql.SQLException: ORA-06576: not a valid function or procedure name

When saveDepartment() is invoked, I am getting exception mentioned in the title. After searching for solution for a while I came up with another similar post on stackoverflow which doesn't match the problem scenario I am facing.
Dao class:
#Repository
public class DepartmentDaoImpl implements DepartmentDao {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public void saveDepartment(Department department) {
Session session = sessionFactory.getCurrentSession();
session.save(department);
}
}
Bean configuration section for hibernate:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="net.therap.domain.tmp"/>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Any suggestion or solution regarding the problem is appreciated.
ORA-06576 error code and oracle11g tag are suggesting you're using Oracle 11g Database.
Hibernate's Oracle10gDialect is compatible with that version, so you should use following dialect configuration:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="net.therap.domain.tmp"/>
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

weblogic jndi datasource issue with spring application

I have created a oracle datasource in weblogic with the name jdbc/myDS.
Weblogic created a xml file in mydomain/config/jdbc and the configuration works from the weblogic admin console. Test connection is working. My spring context file details are:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/myDS"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<util:map>
<entry key="hibernate.hbm2ddl.auto" value="update" />
<entry key="hibernate.show_sql" value="true" />
</util:map>
</property>
</bean>
<bean id="myDAO" class ="com.example.MyDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My Java class is:
public class MyDAOImpl implements MyDAO{
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void persistPerson(Person person) {
Session session = getSessionFactory().openSession();
try {
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
}catch(HibernateException he) {
he.printStackTrace();
} finally {
session.close();
}
}
}
An error occurred during activation of changes, please see the log for
details.
Message icon - Error weblogic.application.ModuleException:
Message icon - Error While trying to lookup 'jdbc.myDS' didn't find subcontext 'jdbc'. Resolved ''; remaining name 'jdbc/myDS'
The following provides a Spring XML configuration to obtain a datasource by a JNDI name and inject it into Springs AnnotationSessionFactoryBean.
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/YourJndi"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>com.java.model.Employee</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
This example has been sucessfully tested on Weblogic 10.3.4 with Oracle 11g.

Spring + Hibernate4 Error CurrentSessionContext is always null

I'm using Hibernate 4 with spring 3.1 in a simple java Apllication.
I use the following code to create the Spring SessionFactory and then convert it into a hibernate SessionFactory:
pls waht is missing here ... Is this the right way to go?? Or do I miss something..? pls help!
.....
......
context=new ClassPathXmlApplicationContext(new String[]{"spring.xml"});
return (SessionFactory) context.getBean("mySessionFactory");
......
The CurrentSessionContext ofthe sessionfactory is always null!
So I cant execute
sessionFactory.getcurrentSession()
-> gives me an java.lang.NullPointer Exception
myBean Declarations in spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<bean id="mySessionFactory" name="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" scope="singleton">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>TblUrls.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">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.SunOneJtaPlatform</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref local="mySessionFactory" />
</property>
</bean>
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name = "sessionFactory" ref = "mySessionFactory" />
</bean>
<!-- <bean id="myProductDao" class="hib.TblUrlsHome"> -->
<!-- <property name="sessionFactory" ref="mySessionFactory"/> -->
<!-- </bean> -->
</beans>
You have to do
sessionFactory.openSession();
This should solve your problem.

Resources