Spring jdbc:initialize-database not working - spring

I can't get spring to initialize my database, although from what I can see I'm doing this right. I keep getting a org/springframework/dao/DataAccessResourceFailureException.
Here is my springapp-servlet.xml:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:create_products.sql" />
<jdbc:script location="classpath:load_data.sql" />
</jdbc:initialize-database>
The jdbc.properties file is in Java Resources/src and is this:
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost
jdbc.username=sa
jdbc.password=
The create_products.sql is also in Java Resources/src and is this:
CREATE TABLE products (
id INTEGER NOT NULL PRIMARY KEY,
description varchar(255),
price decimal(15,2)
);
The load_data.sql is in the same location and is this:
INSERT INTO products (id, description, price) values(1, 'Lamp', 5.78);
INSERT INTO products (id, description, price) values(2, 'Table', 75.29);
INSERT INTO products (id, description, price) values(3, 'Chair', 22.81);
Any suggestions?
Thanks.

Dave probably you are also getting this error in your springapp-servlet.xml cvc-complex-type.2.4.b: The content of element 'jdbc:initialize-database' is not complete.
One of '{"http://www.springframework.org/schema/jdbc":script}' is expected. ?
The org.springframework.jdbc.datasource.init package provides support for initializing an existing DataSource. Just check if your spring-jdbc version.
Ref: [http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch12s09.html][1]
Just open the spring-jdbc jar and see under: org/springframework/jdbc/datasource if you can see any folder by name init .If init folder doesnt exist, then the version of Spring Framework you are using does not support this feature.

Related

Spring Batch | Does JdbcPagingItemReader<T> supports multiple DataSource to support join query across multiple datasource?

I do have SQL query reader for ItemReader with only single .
But my query exception is to join tables from two different datasource and provide single output result.. something like below
<bean id="userFinder"
class="org.springframework.batch.item.database.JdbcPagingItemReader"
scope="step">
...
...
class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource1" ref="dataSource1" />
<property name="dataSource2" ref="dataSource2" />
<property name="selectClause"
value="SELECT ALIAS1.COL1, ALIAS2.COL2 " />
<property name="fromClause" value="FROM dataSource1.TABLE1.ALIAS1, dataSource2.TABLE 2.ALIAS2" />
</property>
<property name="sortKey" value="WLT_ID" />
</bean>
</property>
in single query you will be not able to join two different database. I think in java you will not able to use two datasource to run one query.
You can write your custom ItemReader and inject both datasource.
retrieve data from both table and do join in java code. but this will be very expensive operation

Spring Batch - Last item from the reader alone is getting updated

I have to read from a file (FlatFile) and update a column if that ID present in the file matches the id in the column.The file is being read properly but only the last id value is getting updated here . Please find the snippet
Job-Config.xml
<bean id="abcitemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" value="file:datafile/outputs/ibdData.txt" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="ID,NAM,TYPE" />
<property name="delimiter" value="|"/>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.pershing.intraware.springbatch.mapper.abcFieldsetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="abcitemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql"><value>UPDATE TEST_abc SET BIZ_ARNG_CD = CASE WHEN ID IN (SELECT ID FROM TEST_abc WHERE ID= ? and MONTH=(to_char(sysdate, 'MM')) AND YR =(to_char(sysdate, 'YY'))) THEN 'Y' ELSE 'N' END</value></property>
<!-- It will take care matching between object property and sql name parameter -->
<property name="itemPreparedStatementSetter" ref="testPrepStatementSetter" />
</bean>
</beans>
Setter.java
public class IDItemPreparedStatementSetter implements ItemPreparedStatementSetter<Test> {
#Override
public void setValues(Test item, PreparedStatement ps) throws SQLException {
// TODO Auto-generated method stub
ps.setString(1, item.getID());
}
}
Your query is updating each row of database every time it is fired. You need to restrict that. Currently; it must be setting the BIZ_ARNG_CD to 'Y' for records with ID equal to the ID of the last record passed to the writer.
You can fix this in 2 ways -
Default the database column to 'N' and don't set it to 'N' in the update statement
Add where clause in update script ( BIZ_ARNG_CD != 'Y')

spring mvc and jdbc

I am beginning with spring and I am working on the web mvc. When not in MVC, as pointed in some tutorial, I would specify the data source in beans.xml and call this file with ApplicationContext object, and creating an object by passing the data source. And that worked for me. and when I came back to MVC, I created the data source in my name-servlet.xml file by using
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/hello"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
and I have a superclass used for my service classes for data access, only with method setDataSource. and here is my sample.
#Resource(name="dataSource")
public void setDataSource(DataSource dataSource){
this.dataSource=dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
but I am still getting a null pointer exception when working with the dataSource. please what am i missing?

In-memory database is not created but logs shows that DDL was executed

I am trying to setup spring environment to run with in memory database which is automatically created based on provided mappings. During execution I can see in logs that DDL statements are executed, but when hibernate tries to insert data into created tables, I am getting 'Table not found' exception.
What can be a problem?
Using spring 3.1.1 and Hibernate 4.1.1 and H2 version 1.3.165.
Logs looks like (only revelant records left):
INFO at '25-04-2012 13:23:56.318' by thread 'main' from category 'org.hibernate.tool.hbm2ddl.SchemaExport':
HHH000227: Running hbm2ddl schema export
DEBUG at '25-04-2012 13:23:56.318' by thread 'main' from category 'org.hibernate.SQL':
drop table DUMMIES if exists
Hibernate:
drop table DUMMIES if exists
DEBUG at '25-04-2012 13:23:56.318' by thread 'main' from category 'org.hibernate.SQL':
create table DUMMIES (
id bigint generated by default as identity,
title varchar(255),
primary key (id),
unique (title)
)
Hibernate:
create table DUMMIES (
id bigint generated by default as identity,
title varchar(255),
primary key (id),
unique (title)
)
INFO at '25-04-2012 13:23:56.334' by thread 'main' from category 'org.hibernate.tool.hbm2ddl.SchemaExport':
HHH000230: Schema export complete
INFO at '25-04-2012 13:23:56.334' by thread 'main' from category 'org.springframework.context.support.ClassPathXmlApplicationContext':
Bean 'mySessionFactory' of type [class org.springframework.orm.hibernate4.LocalSessionFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO at '25-04-2012 13:23:56.631' by thread 'main' from category 'org.springframework.orm.hibernate4.HibernateTransactionManager':
Using DataSource [org.springframework.jdbc.datasource.SimpleDriverDataSource#a86d12] of Hibernate SessionFactory for HibernateTransactionManager
WARN at '25-04-2012 13:23:56.865' by thread 'main' from category 'org.hibernate.engine.jdbc.spi.SqlExceptionHelper':
SQL Error: 42102, SQLState: 42S02
ERROR at '25-04-2012 13:23:56.865' by thread 'main' from category 'org.hibernate.engine.jdbc.spi.SqlExceptionHelper':
Table "DUMMIES" not found; SQL statement:
insert into DUMMIES (id, title) values (null, ?) [42102-165]
Beans.xml looks like ('mypackage' is a replacement for full package name):
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:" />
...
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan">
<array>
<value>mypackage.entities</value>
</array>
</property>
</bean>
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="daoMethods" expression="execution(* mypackage.*Dao.*(..))" />
<aop:advisor advice-ref="requiredTxAdvice" pointcut-ref="daoMethods" />
</aop:config>
<tx:advice id="requiredTxAdvice" transaction-manager="myTransactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="dummyDao" class="mypackage.DummyDaoImpl">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
hibernate.properties looks like:
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.id.new_generator_mappings=true
hibernate.hbm2ddl.auto=create-drop
(create does not worked too)
When you specify database URL as jdbc:h2:mem: H2 creates new database for each connection, thus each Hibernate session sees its own empty database.
So, you need to specify database name, to access the same database from different connections. Also you need to prevent the database from being closed when it has no active connections. The resulting URL looks like this: jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1.
Also note that Spring provides built-in support for embedded databases, see 12.8 Embedded database support.

Spring Programmatic Jdbc Transaction rollback doesn't work

I use spring transaction to include a few db update operation into a single transaction. let say there 2 db updates within a single transaction. the update 1 is successful while the second fails. my problem is when such a case happens, the first db update get committed to db even though the second db update failed which leads to transaction rollback.
XML declaration:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="test" />
<property name="password" value="test" />
</bean>
<bean id="testDao" class="dao.TestDao">
<constructor-arg >
<ref local="simpleJdbcTemplate" />
</constructor-arg>
<constructor-arg >
<ref local="txManager" />
</constructor-arg>
</bean>
java code:
public class DaoCallback extends TransactionCallbackWithoutResult {
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
try{
dbUpdate1();
dbUpdate2();
}catch(Exception e){
arg0.setRollbackOnly();
}
}
i intentionally make the dbUpdate1 to success and the dbUpdate2 to fail so as the test out whether the rollback really works. When I debug through my code, i can see that the control flow run into the catch exception and the "setRollbackOnly()" method is called.
But when I check the database, I can see the change from dbUpdate1(). So please help explain what is wrong here?
Dara kok,
I've found out the problem. It's not the code i've that cause the problem. it's MySQL data storage configuration. MyISAM doesn't support transaction.
Spring should have shown some kind of error message so that developer can know that a transaction is being called on a database engine without transaction support.

Resources