spring Transaction management not working - java

I was using programmatic transaction management in spring, now I have switched to declarative transaction management.
SessionFactory
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.hcentive.cig.domain" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
TransactionManager
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory">
<beans:ref bean="sessionFactory" />
</beans:property>
</beans:bean>
Now If run my code
#Override
#Transactional
public Request saveRequest(Request request) {
sessionFactory.getCurrentSession().save(request);
return request;
}
I get exception save is not valid without an active transaction
if I remove below line
<beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>
I get
No CurrentSessionContext configured!

You definitely don't need this setting:
<beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>
Spring Transaction Management layer should bind the Hibernate Session to the current running Thread.
The settings are fine, the only thing that might cause it comes from this statement of yours:
no it is getting called from service layer , and also I have tried
moving # transactional to service layer
You need to expose this method:
Request saveRequest(Request request);
through a Service interface, that you inject in any other component (web or other service layer beans).
To validate this, you can place a debug break-point in the saveRequest method implementation, and look for the TransactionInterceptor up the call-stack. If it's not there, then Spring couldn't wrap your method call into a Transaction Aspect processing logic.

Having your function annotated as Transactional is not necessarily enough. You also need to ensure that:
Your bean gets created via Spring (defined as #Component and found via componentScan OR declared in xml configuration)
The reference to your bean needs to be obtained through Spring dependency injection

For #Transactional to be effective you have to tell the Spring context that you want to use that. Annotations without a processor for that annotation is pretty useless. To enable the processor for the #Transactional annotation add <tx:annotation-driven /> to your context. (As explained here in the reference guide).
Your hibernate configuration is also problematic when using Spring you shouldn't mess around with the hibernate.current_session_context_class configuration property (unless you use some specific JTA provider but apparently you aren't). If you start setting that property you will break proper spring integration for transaction management. Spring already sets that property for you and your setting overrides the default.
Your configuration should look something like this.
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.hcentive.cig.domain" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref bean="sessionFactory" />
</beans:bean>
<tx:annotation-driven />

Related

java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager error in Spring MVC while pulling data

I am trying to learn creating ReST API end points using spring mvc and Hibernate without using springboot. When I am running my end point , I am getting internal server error saying that ,
java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.createQuery(String, java.lang.Class)" because "this.entityManager" is null.
My spring-servlet.xml file under src/main/webapp/web-1nf is like the following,
<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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql://localhost:5432/company" />
<beans:property name="username" value="postgres" />
<beans:property name="password" value="postgresql" />
<!--<property name="socketTimeout" value="10"/>-->
<beans:property name="connectionProperties">
<beans:props>
<beans:prop key="socketTimeout">10</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.springmvc.Employee</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop
key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<context:component-scan base-package="com.springmvc" />
<tx:annotation-driven transaction-manager="transactionMgr"/>
<beans:bean id="transactionMgr"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="mgrFactory"/>
</beans:bean>
<beans:bean id="mgrFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.springmvc"/>
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</beans:prop>
<beans:prop key="hibernate.dialect">${hibernate.dialect}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</beans:prop>
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.format_sql">${hibernate.format_sql}</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
</beans:beans>
My controller is ,
#RestController
#RequestMapping("/mvchibernate")
public class CompanyController {
#Autowired
EmployeeService employeeService;
#GetMapping(value = "/getAllEmployees")
public List<Employee> getEmployeesList() {
#SuppressWarnings("unchecked")
List<Employee> listOfEmployees = employeeService.getAllEmployees();
return listOfEmployees;
}
}
And my service class like the following,
#Service
public class EmployeeService {
#Autowired
EmployeeDAO employeeDaoObj;
public List getAllEmployees() {
return employeeDaoObj.getAllEmployees();
}
}
And DAO implementation ,
#Repository
public class EmployeeDAO {
#PersistenceContext private EntityManager entityManager;
public List<Employee> getAllEmployees() {
String jpql = "SELECT e FROM Employee e";
TypedQuery<Employee> query = entityManager.createQuery(jpql, Employee.class);
return query.getResultList();
}
}
Here in my DAO class I autowired the entitymanager.And while running I am getting Cannot invoke javax.persistence.EntityManager and last showing that because "this.entityManager" is null.
So can anyone guide me to resolve this issue or kindly refer any documentation to follow please?
Edit from my previous answer, After reviewing your code below is what you are currently doing:
You created PersistenceConfig.java with Configuration annotation. This class is empty & it looks you have commented it after creating & defining beans.
Spring is actually checking PersistenceConfig.java for finding configurations instead of going to your xml.
Move your xml config to src/main/resources & for supporting best practice rename it to persistence.xml.
Now, you have to tell spring to read your configs from persistence.xml instead of looking anywhere else. Comment out Configuration annotation from PersistenceConfig.java & use below annotation in your main class :
:
#SpringBootApplication
#ImportResource({ "classpath:persistence.xml" })
public class SpringMvcHibernateRestApiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMvcHibernateRestApiApplication.class, args);
}
}
Also, I suggest to use org.springframework.orm.hibernate5.LocalSessionFactoryBean instead of
org.springframework.orm.hibernate4.LocalSessionFactoryBean as it will be inline with your latest spring & jpa versions.
Once you used this, you will be able to see entitymanager got created properly.
Edit : As per OP's comment, point number 5 is not required on their machine.
You are referencing the transactionManager bean here:
<tx:annotation-driven transaction-manager="transactionManager"/>
But the bean is actually named transactionMgr:
<beans:bean id="transactionMgr"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="MgrFactory"/>
</beans:bean>
You should reference the correct name:
<tx:annotation-driven transaction-manager="transactionMgr"/>
I do believe there are two options:
define PersistenceAnnotationBeanPostProcessor bean - it is responsible for injecting #PersistenceContext fields (though documentation says it should be registered automatically, m.b. it is worth to debug it to understand the reason):
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
define EntityManager factory bean and use #Autowired instead of #PersistenceContext:
<bean id="emf" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="mgrFactory"/>
</bean>

Hibernate : C3p0 pool configuration slowing down entire server.

I am working on a Spring-MVC application in which we are using Hibernate and c3p0 for Database transactions and connection pooling. Most of the time it works really good, no issues. But in certain situations I have to copy a lot of objects and files in the current transaction. When that happens, the entire server slows down and finally I start getting could not rollback exception . Anything wrong with my c3p0 settings? Thank you.
pom.xml :
<!--- Hibernate dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.9.Final</version>
</dependency>
root-context.xml :
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.postgresql.Driver"/>
<beans:property name="url"
value="jdbc:postgresql://localhost:PORT/DB_NAME"/>
<beans:property name="username" value="USERNAME"/>
<beans:property name="password" value="PASSWORD"/>
<beans:property name="removeAbandoned" value="true"/>
<beans:property name="removeAbandonedTimeout" value="20"/>
<beans:property name="defaultAutoCommit" value="false"/>
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<!--<beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop>-->
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="cache.use_second_level_cache">true</beans:prop>
<beans:prop key="cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<beans:prop key="show_sql">false</beans:prop>
<beans:prop key="hibernate.c3p0.min_size">1</beans:prop>
<beans:prop key="hibernate.c3p0.max_size">750</beans:prop>
<beans:prop key="hibernate.c3p0.acquire_increment">1</beans:prop>
<beans:prop key="hibernate.c3p0.idle_test_period">1000</beans:prop>
<beans:prop key="hibernate.c3p0.max_statements">150</beans:prop>
<beans:prop key="hibernate.c3p0.timeout">1200</beans:prop>
<beans:prop key="hibernate.connection.release_mode">auto</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
Thank you.
For starters you aren't using C3P0 simply because you have configured the org.apache.commons.dbcp.BasicDataSource as a DataSource and are injecting that into your LocalSessionFactoryBean. This basically renders all the hibernate.c3p0 settings useless as they will be ignored.
Next you have issues with processing large amounts of data and I highly doubt the issue is your DataSource or connection pool but rather the way you are processing your entities and how you have configured Hibernate.
To speedup batch processing you want to flush every x records to the database and clear the first level cache. Why do you want to do this you might wonder. It has all to do with how Hibernate works, when you persist an entity what Hibernate does it will add it to the first level cache (the Session or EntityManager in case of JPA). Each time you add an item to the first level cache it will do a dirty check on ALL of the entities in the first level cache to determine if something needs to be flushed. Now this will be fast for the first few entities but will become increasingly slower and slower.
Lets configure and code things for a batch size of 50.
First you want to configure hibernate to have a proper batch size and you want to order the insert and update statements. If you do this you can benefit from the fact that JDBC can now do a Batch Update (i.e. one insert or update statement to modify 50 records instead of 50 single insert/update statement).
Hibernate Configuration
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<!--<beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop>-->
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">true</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
<beans:prop key="hibernate.order_inserts">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<!-- If you use versioned entities set this to true as well -->
<beans:prop key="hibernate.jdbc.batch_versioned_data">true<beans:prop>
</beans:props>
</beans:property>
</beans:bean>
Code Modification
public void yourLargeDataSetProcessingMethod() {
Session session = sessionFactory.getCurrentSession();
int i = 0;
for (YourItem item : List<YourItem> items) {
i++:
// Here will be processing / creation
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
}
This will probably speed up your processing and database locking.
A final note, instead of Commons DBCP or C3P0 I would suggest to use HikariCP as the connection pool. It is very small and very fast and actively maintained (whereas C3P0 has been dormant for quite some time already).
Here is a nice resource (with benchmarks etc.) on what each setting does and add or removes performance wise and how to configure things properly.

Hibernate, PostgreSQL : Write to 2 different databases on different servers.

I am working on a Spring-MVC application which we have running on 2 servers, one is our testing server, 2nd one is our live server. Is there any way that I can configure Hibernate to write any and all DB related queries on both servers. Example : User A saved Object A on live server, then write the same object on Test-server, vice-versa is not required. Our test and live server both have same setting and same database. Thank you.
root-context.xml :
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.postgresql.Driver"/>
<beans:property name="url"
value="jdbc:postgresql://localhost:PORT/DB_NAME"/>
<beans:property name="username" value="USERNAME"/>
<beans:property name="password" value="PASSWORD"/>
<beans:property name="removeAbandoned" value="true"/>
<beans:property name="removeAbandonedTimeout" value="20"/>
<beans:property name="defaultAutoCommit" value="false"/>
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.tooltank.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<!-- <beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop>-->
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="cache.use_second_level_cache">true</beans:prop>
<beans:prop key="cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<beans:prop key="show_sql">false</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<hibernate.version>4.3.9.Final</hibernate.version>
If anymore data is required, please let me know. Thank you.
Not in any way that you're probably hoping for. They have completely different transactional contexts, so you can't just pretend that 2 databases are one.
What if one database throws an exception and the other one doesn't? Did the tx commit or roll back? Hibernate certainly doesn't expect it to be "half success".
You could make the test server a slave of the live server and just write to the live server. This is not a simple solution either and can be outright stupid.

dificullty while using two databases in the spring hibernate application

I am trying to use 2 databases in my spring project. It is working fine if I use 1 database but when add other databases I am getting following error message.
org.hibernate.HibernateException: No Session found for current thread
dispatcher-servlet
<beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="sample" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.kendoui.spring.models.Constraint</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.format_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<beans:bean id="Ascent" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<beans:property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=Ascent;" />
<beans:property name="username" value="sa" />
<beans:property name="password" value="abc123" />
<beans:property name="maxActive" value="1" />
<beans:property name="maxIdle" value="1" />
</beans:bean>
<beans:bean id="sessionFactory2" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="Ascent" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.kendoui.spring.models.ItemOperationSequence</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.format_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory2" />
</beans:bean>
<!-- Enable annotation driven transactions. Required by getCurrentSession(). -->
<tx:annotation-driven/>
DAO implemantation
#Transactional("transactionManager2")
#Component
public class ItemOprSeqDaoImpl implements ItemOprSeqDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public List<ItemOperationSequence> getList(String Itemcode) {
Session session = sessionFactory.getCurrentSession();
String queryStr= "select * from [#is_itemtrvoprdetails]";
Query query= session.createSQLQuery(queryStr).addEntity(ItemOperationSequence.class);
List <ItemOperationSequence> d=query.list();
return d;
}
}
I tried many different things but it is not working.
I tried using <beans:qualifier value="Ascent" /> in my servlet
and
#Qualifier(value="SessionFactory2") in my DAO
but nothing seems to work.
Anyone knows the answer to this problem. I would really appreciate if you could help.
Thanks in advance.
<tx:annotation-driven/> should be declared twice once for each transaction manager.
<tx:annotation-driven transaction-manager="transactionManager2"/>
and
<tx:annotation-driven transaction-manager="transactionManager"/>
Also add #Qualifier for
#Autowired
#Qualifier(value="SessionFactory2")
private SessionFactory sessionFactory;
You need to define a ChainedTransactionManager with both HibernateTransactionManagers as input.
I am not used to spring xml configuration, but it should look like this.
Than just use only #Transactional without a value.
<beans:bean id="transactionManager1" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<beans:bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory2" />
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.data.transaction.ChainedTransactionManager">
<beans:constructor-arg>
<list>
<beans:ref bean="transactionManager1" />
<beans:ref bean="transactionManager2" />
</list>
</beans:constructor-arg>
</beans:bean>
Okay I solved the problem by doing this.
first declared transaction-manager
<tx:annotation-driven transaction-manager="transactionManager1"/>
Then in my DAO used
#Transactional("transactionManager2")
#Component
public class ItemOprSeqDaoImpl implements ItemOprSeqDao {
#Autowired
#Qualifier("sessionFactory2")
private SessionFactory sessionFactory;
//then rest of the code
}
Its working fine now. Thanks you guys for your help.

How to use JNDI DataSource provided by WebLogic in Spring?

It is said in Spring javadoc article about DriverManagerDataSource class, that this class is very simple and that it is recommended
to use a JNDI DataSource provided by the container. Such a DataSource can be exposed as a DataSource bean in a Spring ApplicationContext via JndiObjectFactoryBean
The question is: how to accomplish this?
For example if I wish to have DataSource bean to access my custo oracle database, what I require then? What to write in context configuration etc?
To access a JNDI data source you do something like:
<bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDatabase"/>
</bean>
or look et the spring 'jee' schema.
The details of the database connection are configured in WebLogic, the application accesses
the database through the jndi name.
Or use Java based configuration and do it like this:
#Bean(destroyMethod = "")
public DataSource dataSource() throws NamingException{
Context context = new InitialContext();
return (DataSource)context.lookup("jdbc.mydatasource");
}
There is another option:
<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/MyLocalDB"
expected-type="javax.sql.DataSource" />
You can use following jndi configuration.
<beans:bean id="weblogicDataSource" class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<beans:property name="jndiName" value="ConnectionPoolJNDINameAsConfigured"></beans:property>
<beans:property name="jndiEnvironment">
<beans:props>
<beans:prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</beans:prop>
<beans:prop key="java.naming.provider.url">iiop://localhost:7001</beans:prop>
</beans:props>
</beans:property>
<beans:property name="serviceInterface" value="javax.sql.DataSource"></beans:property>
</beans:bean>
and you make the reference to your injected class file as
<beans:bean id="xxxx" class="xxxxxxxx">
<beans:property name="wlDataSource" ref="weblogicDataSource" />
</beans:bean>
and in your implemenation class, use
import javax.sql.DataSource;
make an instance as
private DataSource wlDataSource;
and corresponding setter. Now you are free to use JDBCTemplate or SimpleJDBCCall etc as per your implementation thinking.
Hope this will help.

Categories