I'm trying to insert value into Oracle DB using JdbcTemplate, but its throwing the following exception:
Can't access the database values using JdbcTemplate.
This is how I am trying to insert the values to the DB:
package com.sample.common.Dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class UserDao extends JdbcDaoSupport {
public void insert(){
System.out.println("Tring to insert");
String sql = "INSERT INTO SB_TBL_USER (user_id,user_password,user_name,user_email,user_mobile)"+" "
+"VALUES ('test12', 't1est1', 't2est2', 't7est2','t7estm')";
getJdbcTemplate().update(sql);
}
public static void main(String args[]){
UserDao dao= new UserDao();
dao.insert();
}
}
DataSourceConfiguration.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="sbjdev" />
<property name="password" value="sbjdev" />
</bean>
<bean id="UserDao" class="com.mPowerQuartz.common.Dao.UserDao.java">
<property name="dataSource" ref="dataSource" />
</bean>
This exception is most likely thrown by your own code.
And it's most likely thrown because the dataSource field of the UserDao is null.
The reason for that is that you're not using Spring correctly. Instead of asking Spring to create the UserDao and inject the DataSource in that Spring bean, you're creating the UserDao yourself, using new. So no Spring context is ever used, and Spring doesn't play any role in your code.
Read the Spring documentation to understand how to create a Spring application context and get a bean from it.
I found the answers they are..
1)ApplicationContext and bean is not initialized, which will look like..
ApplicationContext ctx = new ClassPathXmlApplicationContext("userconfig.xml");
UserDao usr = (JobDetailsDao) ctx.getBean("UDao");
2)In configuration xml, Dao and Dao implementation are not mapper. Which looks like.
<bean id="UserDao" class="com.mPowerQuartz.common.DaoImpl.UserDaoImpl">
<property name="jdbcTemplate"> <ref bean = "jdbcTemplate" ></ref>
</property>
</bean>
Related
i want to test a class with a Datasource bean injected, but i don't know how to Mock the Bean Datasource(i dont' have the class but only bean configuration).
My class is like this:
public class Configurazione {
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
...
}
my beans:
<bean id="Configurazione" class="com.company.configurazione.Configurazione">
<property name="dataSource" ref="dataSourceMySql" />
</bean>
<bean name="dataSourceMySql"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="..." />
<property name="username" value="..." />
<property name="password" value="..." />
</bean>
how can i test the class Configurazione with mockito and inject the datasource bean?
i've no class DataSource to #mock in the test class Configurazione.
Usually for testing purposes additional Spring application context is created. And you can define beans differently there. For example you can use in-memory HSQL database as your datasource
<jdbc:embedded-database id="dataSource" type="HSQL" >
<jdbc:script location="scripts/ddl/sequences/*"/>
<jdbc:script location="scripts/ddl/tables/*"/>
<jdbc:script location="scripts/dml/*"/>
</jdbc:embedded-database>
To use this snippet of code as-is you need to add hsql dependency to your project and adjust paths to scripts (these scripts create and populate database schema used in your tests).
And you run your tests with that test application context
Below is the way, i am using jdbc connectivity for my spring mvc.
I have some technical doubts, which follows-
1.
As i have invoked datasource object in every bean that requires db connectivity. Is it the right way of doing it?
What if i don't want a particular repository object to be instantiated when the application starts up
(because I'm not sure when user will invoke the object, so why instantiate it at the very beginning)?
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnection}" />
</bean>
<bean id="ustestuthenticationRepository"
class="com.test.repository.impl.UstestuthenticationRepositoryImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="someclass"
class="com.test.repository.impl.someclass">
<property name="dataSource" ref="dataSource" />
</bean>
2.
#Qualifier("dbDataSource")
private static DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
and then creating
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
I'm not sure if this is the right way of invoking datasource.If each and every Repository object creates separate jdbctemplate, is it something appropriate?
In every repository class, i am invoking datasource in the folowing way-
Modified Code
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<bean id="someclass" class="com.era.repository.impl.someclass">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
and implementation in someclass is -
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
then only accessing jdbcTemplate variable wherever is required.
Am i doing it correctly now? Please advise.
What you done is not an error. It is possible to work that way.
However.
It means you will simply work with JDBC directly.
It means, you need handle transactions "manually".
It is hard and a lot of code.
You better use spring data and hibernate.
Or spring data and JPA.
Anyway, spring data will help you to manage all resources and will simplify data access for you.
If you already on spring MVC, take also spring data. Why bother?
Official spring data example:
https://spring.io/guides/gs/accessing-data-jpa/
I have a webapp using Hibernate 4.1 and Spring 3.1 and JSF 1.2 (myFaces).
I have this "LazyInitializationException" each time I try to access one of my pages
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at £org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at foo.data.bo.implementations.EOServiceType_$$_javassist_10.getTechKey(EOServiceType_$$_javassist_10.java)
at foo.converter.EOServiceTypeConverter.getAsString(EOServiceTypeConverter.java:36)
at org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils.getConvertedStringValue(RendererUtils.java:648)
at org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.getSubmittedOrSelectedValuesAsSet(HtmlRendererUtils.java:362)
at org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.internalRenderSelect(HtmlRendererUtils.java:337)
at org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.renderMenu(HtmlRendererUtils.java:288)
at org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlMenuRendererBase.encodeEnd(HtmlMenuRendererBase.java:57)
at org.apache.myfaces.renderkit.html.ext.HtmlMenuRenderer.encodeEnd(HtmlMenuRenderer.java:70)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:649)
... 50 more
I think I missunderstood something because I don't know How to give the "session" to my classes.
For info, here are some of my configuration files :
spring-config.xml:
<context:annotation-config />
<context:component-scan base-package="foo" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="namingStrategy">
<ref bean="oracleNamingStrategy" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<alias name="jndiDataSource" alias="dataSource" />
<bean name="oracleNamingStrategy"
class="org.hibernate.cfg.ImprovedNamingStrategy">
</bean>
<bean name="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/fooDS</value>
</property>
</bean>
My java class EOServiceType
#Entity
#Table(name="EOSERVICETYPE")
public class EOServiceType implements IEOServiceType {
#Id
#Column(name="EOSERVICETYPE_ID")
private long techKey;
#Column(name="H_PROPERTY")
private String property;
#Column(name="H_DESCRIPTION")
private String description;
//... + all getters and setters
}
My DAO implementation for Hibernate EOServiceTypeDaoHibernateImpl
#Repository("eOServiceTypeDao")
public class EOServiceTypeDaoHibernateImpl implements IEOServiceTypeDao {
#Autowired
private SessionFactory sessionFactory;
public void save(IEOServiceType serviceType) {
sessionFactory.getCurrentSession().save(serviceType);
}
public void update(IEOServiceType serviceType) {
sessionFactory.getCurrentSession().update(serviceType);
}
//... and some other CRUD operations...
}
My POJO Service implementation for Hibernate EOWebStaffServicesImpl
#Service
public class EOWebStaffServicesImpl implements IEOWebStaffServices {
#Autowired
private SessionFactory sessionFactory;
//...
#Autowired
private IEOServiceTypeDao eoServiceTypeDao;
public void saveOrUpdateEOServiceType(IEOServiceType eoServiceType) {
try {
eoServiceTypeDao.saveOrUpdate(eoServiceType);
} catch (DataIntegrityViolationException e) {
DuplicateKeyException exception= new DuplicateKeyException("Duplicate business key for " + eoServiceType,e);
throw exception;
}
}
public void deleteEOServiceType(IEOServiceType eoServiceType) {
eoServiceTypeDao.delete(eoServiceType);
}
My Hibernate Config file :
<hibernate-configuration>
<session-factory>
<property name="hibernate.mapping.precedence">hbm, class</property>
<property name="show_sql">false</property>
<property name="format_sql">true</property>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="jdbc.batch_size">20</property>
<mapping class="foo.data.bo.implementations.EOServiceType"/>
<!-- ... and other mappings -->
</session-factory>
</hibernate-configuration>
Does any body have a tip to help me ? I read some articles and post but did not really find a solution to my problem.
Best regards,
Kamran
I had the same kind of problem several weeks ago. I obviously forgot to annotate my method which is interacting with Hibernate.
I recommend you the
#Transactional
annotation. It should fix your problem.
Otherwise here is the related Hibernate documentation:
Sessions and Transactions
I think this happens because you don't use transactions in your DAO classes. Hibernate will not work with Spring outside of the transaction. You can define declarative transactions with Spring (annotate necessary classes with #Transactional annotation). Here is a link to Spring reference documentation about Transactions.
Also you should inject SessionFactory to your bean before using it:
#autowired
private SessionFactory sessionFactory;
What are you planing to archive with the SessionFactory in your service class?
Anyway, i think the problem is that you are trying to access a detached object with lazy properties. (That's usually the case when you see that exception)
Is that all the code there is of your POJOs?
I have a table in Oracle11 DataBase with two columns (KEY(varchar2),PROPERTY(varchar2)).
By using Spring framework I want to load the whole content (All the rows) from the table to the Spring Bean so that instead of getting value from DataBase all the time I can use the Bean.
I used Bean class "org.apache.commons.configuration.DatabaseConfiguration". It is working fine but this bean class do not have the provision to load the whole table content into it.
PFB, my Spring-config.xml:
<bean name="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="commonsConfigurationFactoryBean"/>
</bean>
<bean name="commonsConfigurationFactoryBean"
class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
<constructor-arg ref="databaseConfiguration"/>
</bean>
<bean name="databaseConfiguration"
class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
<constructor-arg type="java.lang.String" index="1" value="schema.Table_Name1"/>
<constructor-arg type="java.lang.String" index="2" value="KEY"/>
<constructor-arg type="java.lang.String" index="3" value="PROPERTY"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:SYSTEM_NS:PORT:sid"/>
<property name="username" value="xxxx"/>
<property name="password" value="xxxx"/>
</bean>
Java Code:
ApplicationContext classpathCtx = new ClassPathXmlApplicationContext("Spring-config.xml");
DatabaseConfiguration dBConfig = (DatabaseConfiguration)classpathCtx.getBean("databaseConfiguration");
// To display the value in the property column by sending the value of column KEY
System.out.println(dBConfig.getProperty("Value in the KEY column"));
The Above code is working fine. But each time I am sending the key to DatabaseConfiguration it is internally making a DataBase call to get the property which I do not want to happen.
The whole of the above concept is all about trying to store all the data present in .properties to DB and fetching it from the DB to my Java code.
You could create a FactoryBean that creates a properties object by reading all keys from the databaseConfiguration and copying them to the created properties object.
This properties object is then a singleton, and can be used as such in your spring config.
<bean name="properties" class="...ConfigurationPropertiesFactoryBean">
<property name="configuration" ref="databaseConfiguration"/>
</bean>
public class ConfigurationPropertiesFactoryBean implements FactoryBean<Properties>
{
private Properties props = new Properties();
public void setConfiguration(Configuration configuration)
{
props.put ...
}
public Properties getObject()
{
return props;
}
}
Or instead of a DatabaseConfiguration, you could use JdbcTemplate:
<bean name="properties" class="...DataSourcePropertiesFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
public class DataSourcePropertiesFactoryBean implements FactoryBean<Properties>
{
private Properties props = new Properties();
public void setDataSource(DataSource dataSource)
{
props = new JdbcTemplate(dataSource).query("SELECT KEY, PROPERTY FROM ...",
new ResultSetExtractor(){
public void Properties extractData(ResultSet rs)
{
props.put(...);
}
});
}
public Properties getObject()
{
return props;
}
}
I'm trying to set up a Spring JPA Hibernate simple example WAR for deployment to Glassfish.
I see some examples use a persistence.xml file, and other examples do not.
Some examples use a dataSource, and some do not. So far my understanding is that a dataSource is not needed if I have:
<persistence-unit name="educationPU"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.coe.jpa.StudentProfile</class>
<properties>
<property name="hibernate.connection.driver_class"
value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/COE" />
<property name="hibernate.connection.username" value="root" />
<property name="show_sql" value="true" />
<property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
I can deploy fine, but my EntityManager is not getting injected by Spring.
My applicationContext.xml:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="educationPU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="StudentProfileDAO" class="com.coe.jpa.StudentProfileDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="studentService" class="com.coe.services.StudentService">
</bean>
My class with the EntityManager:
public class StudentService {
private String saveMessage;
private String showModal;
private String modalHeader;
private StudentProfile studentProfile;
private String lastName;
private String firstName;
#PersistenceContext(unitName="educationPU")
private EntityManager em;
#Transactional
public String save()
{
System.out.println("*** em: " + this.em); //em is null
this.studentProfile= new StudentProfile();
this.saveMessage = "saved";
this.showModal = "true";
this.modalHeader= "Information Saved";
return "successs";
}
My web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Are there any pieces I am missing to have Spring inject "em" in to StudentService?
Just to confirm though you probably did...
Did you include the
<!-- tell spring to use annotation based congfigurations -->
<context:annotation-config />
<!-- tell spring where to find the beans -->
<context:component-scan base-package="zz.yy.abcd" />
bits in your application context.xml?
Also I'm not so sure you'd be able to use a jta transaction type with this kind of setup? Wouldn't that require a data source managed connection pool? So try RESOURCE_LOCAL instead.
I'm confused. You're injecting a PU into the service layer and not the persistence layer? I don't get that.
I inject the persistence layer into the service layer. The service layer contains business logic and demarcates transaction boundaries. It can include more than one DAO in a transaction.
I don't get the magic in your save() method either. How is the data saved?
In production I configure spring like this:
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/ThePUname" />
along with the reference in web.xml
For unit testing I do this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" p:persistence-xml-location="classpath*:META-INF/test-persistence.xml"
p:persistence-unit-name="RealPUName" p:jpaDialect-ref="jpaDialect"
p:jpaVendorAdapter-ref="jpaVendorAdapter" p:loadTimeWeaver-ref="weaver">
</bean>
If anyone wants to use purely Java configuration instead of xml configuration of hibernate, use this:
You can configure Hibernate without using persistence.xml at all in Spring like like this:
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}
Since you are not using persistence.xml, you should create a bean that returns DataSource which you specify in the above method that sets the data source:
#Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}
Then you use #EnableTransactionManagement annotation over this configuration file. Now when you put that annotation, you have to create one last bean:
#Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}
Now, don't forget to use #Transactional Annotation over those method that deal with DB.
Lastly, don't forget to inject EntityManager in your repository (This repository class should have #Repository annotation over it).
I have a test application set up using JPA/Hibernate & Spring, and my configuration mirrors yours with the exception that I create a datasource and inject it into the EntityManagerFactory, and moved the datasource specific properties out of the persistenceUnit and into the datasource. With these two small changes, my EM gets injected properly.
This may be old, but if anyone has the same problem try changing unitname to just name in the PersistenceContext annotation:
From
#PersistenceContext(unitName="educationPU")
to
#PersistenceContext(name="educationPU")