Hi i am developing a spring mvc app thats using hibernate to connect to a mysql database that stores files.
I have two methods. one that adds all files from a specific file path of my choosing and another method that invokes a query to return me a list of the files stored from mysql.
The issue is this. When i execute the first method on its own ie populating the database, it works fine i can see the contents of that table from mysql command line. however, when i then execute the query method right after populating it, the contents of that said table is completely gone instantly. Its as if hibernate only stored the data in the mysql temporarily or somewhere in mysql, it deleted data imediatly and doesnt keep it their.
this is the method that populated the table:
/**
* Test Method: ideal for another class to do this kind of work and this
* pass the FileObject into this class
*/
public void addSomeFiles() {
System.out.println("addSomeFiles");
File dir = new File(picturesPath);
String[] fileNames = dir.list();
for (int i = 0; i < fileNames.length; i++) {
System.out.println(fileNames[i]);
File file = new File(picturesPath + "\\" + fileNames[i]);
if (file.isFile()) {
FileObject fileO = contstructFileObject(file);
if (fileO == null) {
System.out.println("fileO is null!!!!!");
} else {
// addFile(fileO);
dbFileHelper.addFile(fileO);
}
}
}
System.out.println("//////////////");
// File file;
}
.........Hibernate template class........
public class DbFileHelper implements DbFileWrapper {
private HibernateTemplate hbTemplate;
//private static final String SQL_GET_FILE_LIST = "select filename, size, id, type from fileobject";
private static final String SQL_GET_FILE_LIST = "select new FileObject(filename, size, id, type) from FileObject";
public DbFileHelper() {
}
public void setHbTemplate(HibernateTemplate hbTemplate) {
System.out.println("setHbTemplate");
System.out.println("///////////////////");
System.out.println("///////////////////");
System.out.println("///////////////////");
this.hbTemplate = hbTemplate;
}
// ////////////////////////////////////////////////
#Override
public String addFile(FileObject file) {
// TODO Auto-generated method stub
System.out.println("addFile using hibernate");
if (hbTemplate == null) {
System.out.println("hbTemplate is null!! why?");
}
hbTemplate.saveOrUpdate(file);
hbTemplate.flush();
return "added succesfuly";
}
And here is the other method that makes the query:
........................
public JSONArray getFileList(String type){
return constructJsonArray(dbFileHelper.getFileList(ALL));
}
private JSONArray constructJsonArray(List<FileObject> fileList ){
JSONArray mJsonArray = new JSONArray();
for (int i = 0; i < fileList.size(); i++) {
System.out.println("fileName = " + fileList.get(i).getFilename() );
//mJson.put("Filename", fileList.get(i).getFileName() );
mJsonArray.add( new JSONObject().put("File ID", fileList.get(i).getId() ));
mJsonArray.add( new JSONObject().put("Filename", fileList.get(i).getFilename() ));
mJsonArray.add( new JSONObject().put("File type", fileList.get(i).getType()));
mJsonArray.add( new JSONObject().put("File Size", fileList.get(i).getSize()));
}
return mJsonArray;
}
..........hibernate Template class.......
private static final String SQL_GET_FILE_LIST = "select new FileObject(filename, size, id, type) from FileObject";
#Override
public List<FileObject> getFileList(String type) {
// TODO Auto-generated method stub
List<FileObject> files = hbTemplate.find(SQL_GET_FILE_LIST);
//hbTemplate.flush();
return files;
}
..........
Finally here is a print screen of what i originaly put inside my table but dissapears on its own:
http://img411.imageshack.us/img411/9553/filelisti.jpg
Am i missing something here?
edit: additional info.
my hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.kc.models.FileObject" >
<class name="com.kc.models.FileObject" table="fileobject">
<id name="id" column="ID">
<generator class="native" />
</id>
<property name="filename" type="string" column="FILENAME" />
<property name="type" type="string" column="TYPE" />
<property name="size" type="double" column="SIZE" />
<property name="file" type="blob" length="1000000000" column="FILE" />
</class>
</hibernate-mapping>
my controller:
#Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// TODO call a method that returns a list of Mobile Apps.
testAddingSomeFilesToDb();
return new ModelAndView("" + "testJsonResponse", "jsonArray",
getFileList() );
}
private void testAddingSomeFilesToDb() {
ctx = new ClassPathXmlApplicationContext("zang-file-service.xml");
FileHelper file = (FileHelper) ctx.getBean("fileHelper");
file.addSomeFiles();
}
/**
* Get file list from sql server based on type
* #return file list in json
*/
private JSONArray getFileList() {
// TODO: Get request parameter that states what type of file extensions
// the client wants to recieve
ctx = new ClassPathXmlApplicationContext("zang-file-service.xml");
FileHelper file = (FileHelper) ctx.getBean("fileHelper");
return file.getFileList("all");
}
Another edit:
my .xml file configuring the session factory and hibernate template
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd -->
<!-- Config properties files -->
<!-- Hibernate database stuff -->
<!-- <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations"> <list> <value>/properties/jdbc.properties</value>
</list> </property> </bean> -->
<!-- <bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" /> <property
name="url" value="${database.url}" /> <property name="username" value="${database.user}"
/> <property name="password" value="${database.password}" /> </bean> -->
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/zangshop" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<!-- LocalSessionFactoryBean u need to put the hbm files in the WEB-INF/classes
root director -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource1"></property>
<property name="mappingResources">
<list>
<value>FileObject.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">create</prop>
</props>
</property>
</bean>
<bean id="hbTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="dbFileHelper" class="com.kc.models.DbFileHelper">
<property name="hbTemplate" ref="hbTemplate"></property>
</bean>
<bean id="fileHelper" class="com.kc.models.FileHelper">
<property name="dbFileHelper" ref="dbFileHelper"></property>
</bean>
</beans>
i have fixed the problem
i changed <prop key="hibernate.hbm2ddl.auto">create</prop>
to <prop key="hibernate.hbm2ddl.auto">update</prop> and it worked
Are you creating/destroying the SessionFactory between calls? Could you have the hbm2ddl.auto property set to create-drop?
Actually, can you show the Hibernate settings?
Reference
Hibernate Core Reference Guide
Table 3.7. Miscellaneous Properties
In my case also table was getting deleted automatically, following solution worked for me:
org.hibernate.dialect.MySQL8Dialect
Appending the version number with the MySQL Dialect.
Because commit was not getting executed earlier with org.hibernate.dialect.MySQLDialect.
Related
I've a context listener where I'm loading all the properties. These properties I'm trying to set in my spring-web.xml, but it throws an exception
Because its not able to fetch and set the property to the xml
Here is my spring-web.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.ibm.as400.access.AS400JDBCDriver" />
<property name="url" value="jdbc:as400://localhost/BB" />
<property name="username" value="{as400.username}" />
<property name="password" value="{as400.password}" />
</bean>
My class of loading properties
public class LoadProperties implements ServletContextListener {
private static Properties properties = null;
private static Logger logger = Logger.getLogger(LoadProperties .class);
#Override
public void contextDestroyed(ServletContextEvent arg0) { }
#Override
public void contextInitialized(ServletContextEvent arg0) {
properties = BBUtil.getProperties("datasource-cfg.properties");
for (String prop : properties.stringPropertyNames()) {
logger.info("Property Loaded :"+properties.getProperty(prop));
if (System.getProperty(prop) == null) {
System.setProperty(prop, properties.getProperty(prop));
}
}
}
}
This class is getting executed and setting the properties under System.
This is my properties file
as400.username=ROOT
as400.password=ROOT
How can I set the values into my spring-web.xml
Any ideas would be greatly appreciated.
we load it using context:property-placeholder
<context:property-placeholder location="classpath:db.properties" />
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="dbHost" value="${db.url}"/>
<property name="dbPort" value="${db.number}"/>
<property name="dbService" value="${db.name}"/>
<property name="dbUrl" value="${db.user}"/>
<property name="dbPassword" value="${db.password}"/>
</bean>
The properties file can also be loaded using prefixes such as http:,file:
The placeholder should be used with a $ sign as follows
<property name="username" value="${as400.username}" />
<property name="password" value="${as400.password}" />
ExtendedIllegalArgumentException essentially indicates that the argument passed is invalid.
I am developing an application for data communication in that i want to communicate to cassandra through ignite c++. when i try to put data to cassandra its works fine. but i can't get the data from the same.
here is my code.
test.h
namespace ignite
{
namespace examples
{
struct Test
{
Test()
{
// No-op.
}
Test(const std::string& assetid, const std::string& asset_desc, const std::string& groupid) :
assetid (assetid), asset_desc (asset_desc), groupid (groupid)
{
// No-op.
}
std::string ToString()
{
std::ostringstream oss;
oss << "Address [street=" << assetid << ", zip=" << asset_desc<< "]";
return oss.str();
}
std::string assetid;
std::string asset_desc;
std::string groupid;
};
}
}
cassandra-config.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.xsd">
<!-- Cassandra connection settings -->
<import resource="file:connection-settings.xml" />
<!-- Persistence settings for 'cache1' -->
<bean id="cache1_persistence_settings" class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
<constructor-arg type="org.springframework.core.io.Resource" value="file:persistence-settings-1.xml" />
</bean>
<!-- Persistence settings for 'cache2'
<bean id="cache2_persistence_settings" class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
<constructor-arg type="org.springframework.core.io.Resource" value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-3.xml" />
</bean>-->
<!-- Ignite configuration -->
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="cacheConfiguration">
<list>
<!-- Configuring persistence for "cache1" cache -->
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="cache1"/>
<property name="queryEntities">
<list>
<bean class="org.apache.ignite.cache.QueryEntity">
<property name="keyType" value="Test"/>
<property name="valueType" value="Test"/>
<property name="fields">
<map>
<!--entry key="assetid" value="assetid"/-->
<entry key="asset_desc" value="asset_desc"/>
<entry key="groupid" value="groupid"/>
</map>
</property>
</bean>
</list>
</property>
<property name="readThrough" value="true"/>
<property name="writeThrough" value="true"/>
<property name="storeKeepBinary" value="true"/>
<property name="cacheStoreFactory">
<bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
<property name="dataSourceBean" value="cassandraAdminDataSource"/>
<property name="persistenceSettingsBean" value="cache1_persistence_settings"/>
</bean>
</property>
</bean>
<!-- Configuring persistence for "cache2" cache
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="cache2"/>
<property name="readThrough" value="true"/>
<property name="writeThrough" value="true"/>
<property name="cacheStoreFactory">
<bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
<property name="dataSourceBean" value="cassandraAdminDataSource"/>
<property name="persistenceSettingsBean" value="cache2_persistence_settings"/>
</bean>
</property>
</bean>
-->
</list>
</property>
<!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
<!--
Ignite provides several options for automatic discovery that can be used
instead os static IP based discovery. For information on all options refer
to our documentation: http://apacheignite.readme.io/docs/cluster-config
-->
<!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
<!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
<property name="addresses">
<list>
<!-- In distributed environment, replace with actual host IP address. -->
<value>127.0.0.1:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
connection-settings.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"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="loadBalancingPolicy" class="com.datastax.driver.core.policies.TokenAwarePolicy">
<constructor-arg type="com.datastax.driver.core.policies.LoadBalancingPolicy">
<bean class="com.datastax.driver.core.policies.RoundRobinPolicy"/>
</constructor-arg>
</bean>
<util:list id="contactPoints" value-type="java.lang.String">
<value>127.0.0.1</value>
</util:list>
<bean id="cassandraAdminDataSource" class="org.apache.ignite.cache.store.cassandra.datasource.DataSource">
<property name="contactPoints" ref="contactPoints"/>
<!-- <property name="user" value="user"/>
<property name="password" value="p#ssw0rd"/> -->
<property name="readConsistency" value="ONE"/>
<property name="writeConsistency" value="ONE"/>
<property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
</bean>
</beans>
persistance-settings.xml
<persistence keyspace="sam" table="user_permission">
<keyPersistence class="com.test.Test" strategy="POJO">
<partitionKey>
<!-- Mapping from POJO field to Cassandra table column -->
<field name="assetid" column="assetid" />
</partitionKey>
</keyPersistence>
<valuePersistence class="com.test.Test" strategy="POJO">
<!-- Mapping from POJO field to Cassandra table column -->
<!-- field name="companyid" column="companyid" />
<field name="company_name" column="company_name" /-->>
<field name="assetid" column="assetid"/>
<field name="asset_desc" column="asset_desc"/>
<field name="groupid" column="groupid"/>
</valuePersistence>
</persistence>
main
int main()
{
IgniteConfiguration cfg;
cfg.springCfgPath = "apache-ignite-fabric-2.0.0-bin/cassandra-config.xml";
Ignite grid = Ignition::Start(cfg);
Cache<Test, Test> cache = grid.GetCache<Test, Test>("cache1");
Test test;
test.assetid = "456dsfds";
Test obj;
obj.asset_desc = "wdsdfsf";
obj.groupid = "sddvwfsf";
cache.Put (test, obj,err);
Test get = cache.Get (test, err);
cout << "Error Found" << err.GetText () << endl;
cout << "Ignite \t" << "\t" << get.asset_desc << "\t" << get.groupid;
}
Test.jar
package com.test;
import java.io.Serializable;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReader;
import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
public class Test implements Binarylizable ,Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
String assetid;
#QuerySqlField(index = true)
String asset_desc;
String groupid;
public String getGroupId() {
return groupid;
}
public void setGroupId(String groupId) {
this.groupid = groupId;
}
public String getAssetid() {
return assetid;
}
public void setAssetid(String assetid) {
this.assetid = assetid;
}
public String getAsset_desc() {
return asset_desc;
}
public void setAsset_desc(String asset_desc) {
this.asset_desc = asset_desc;
}
#Override
public void readBinary(BinaryReader reader) throws BinaryObjectException {
assetid = reader.readString("assetid");
asset_desc = reader.readString("asset_desc");
groupid = reader.readString("groupid");
}
#Override
public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
writer.writeString("assetid", assetid);
writer.writeString("asset_desc", asset_desc);
writer.writeString("groupid", groupid);
}
}
it shows the error like this
Topology snapshot [ver=1, servers=1, clients=0, CPUs=1, heap=0.97GB]
[16:14:20,834][ERROR][sys-#29%null%][CassandraCacheStore] Failed to execute Cassandra CQL statement: select "assetid", "asset_desc", "groupid" from "sam"."user_permission" where "assetid"=? and "asset_desc"=? and "groupid"=?;
class org.apache.ignite.IgniteException: Failed to execute Cassandra CQL statement: select "assetid", "asset_desc", "groupid" from "sam"."user_permission" where "assetid"=? and "asset_desc"=? and "groupid"=?;
I assume that's because you are using this:
<property name="storeKeepBinary" value="true"/>
Current implementation supports only BLOB serialization for binary objects. There is a ticket for this: https://issues.apache.org/jira/browse/IGNITE-5270
As far as you are using C++ to work with Ignite, you are also utilizing BinaryObjects. Current implementation of Cassandra store doesn't support BinaryObjects as cache keys and values.
Because of this, from Ignite C++ client you can't use Cassandra table with 1 partiton key ,3 clustering keys. You can only do it from java client configuring POJO persistence strategy and avoiding BinaryObjects.
There is also a ticket in Ignite JIRA to implement BinaryObjects support in Cassandra store: https://issues.apache.org/jira/browse/IGNITE-5270
I have bean class as below -
public class Account {
private String strAccNumber = "";
private List<Account> accountList = new ArrayList<Account>();
// getter setter
....
...
#Override
public String toString() {
// code for PassThroughLineAggregator
String data="";
for (int j=0; j<accountList.size(); j++) {
Account bean = accountList.get(j);
data = data + bean.getStrAccNumber();
if (j<(accountList.size()-1)) {
data = data + "\n";
}
}
return data;
}
}
to write data I want to set accountList in my config file.
I'm using below code to set bean property.
<bean id="flatFileReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
<property name="resource" value="classpath:springBatch.csv" />
<property name="strict" value="false"></property>
<property name="linesToSkip" value="1" />
<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="ACC#" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="com.abc.reader.AccountDetailsFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="flatFileProcessor"
class="com.abc.processor.AccountItemProcessor"
scope="step"></bean>
<bean id="flatFileWriter"
class="com.abc.FlatFileItemWriterListener"
scope="step">
<property name="resource" value="classpath:springBatch1.csv" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="strAccNumber" />
</bean>
</property>
</bean>
</property>
</bean>
AccountItemProcessor -
public class AccountItemProcessor implements ItemProcessor<Account, List<Account>>{
#Override
public List<Account> process(Account accObj) throws Exception {
// logic..
}
After processing single record in the process step I want to write multiple items(list of item) , how can I write multiple item at a time using arraylist. In my case I want to write data from accountlist.
You'll want to implement your own LineAggregator. That is what provides the String to be written to the file. In your case, you'll write one that returns a String that is really multiple lines.
You can read more about the LineAggregator interface in the documentation here: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/transform/LineAggregator.html
All - In the Spring 3.0, in the applicationContext.xml .... are we supposed to have the bean property name and the reference value to be the same ? If I give a different value, it returns null object. But on giving the same value, it works. For my project, i am supposed to give different values for them. Kindly help. bye, HS
This works: (same values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
This doesn't work: (different values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
bye, HS
My Full Code here:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext.xml --> system's applicationcontext file
applicationContext_MNC.xml ---> my applicationContext for a specific company ... this is getting loaded by my java file, which gets invoked by the web.xml file.
CacheDelegate.java
StatusDBDAO.java
PreXMLWebApplicationContext.java ----> loads my applicationContext file for the specific company.
****** applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean name="exceptionHandler" class="com.megasoft.wir.eStatement.web.interceptor.WIRExceptionHandlerInterceptor"/>
<bean name="security" class="com.megasoft.wir.eStatement.web.interceptor.SecurityInterceptor"/>
<bean name="permission" class="com.megasoft.wir.eStatement.web.interceptor.PermissionInterceptor"/>
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>base</value>
<value>exceptionHandler</value>
<value>security</value>
<value>permission</value>
</list>
</property>
</bean>
</beans>
****** applicationContext_MNC.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
<bean id="MNCCacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
<bean id="MNCStatusDBDAO" class="com.megasoft.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="MNCAdminDataSource" />
</property>
</bean>
<!-- database configuration from property file -->
<bean id="MNCAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.megasoft.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
****** AuthenticateAction.java ******
package com.megasoft.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("MNCCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
*
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
*
<bean id="cacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
*
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
****** WIRAdminBaseAction.java ******
package com.megasoft.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
PreXMLWebApplicationContext.java **
package com.megasoft.wiradmin.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class PreXMLWebApplicationContext extends XmlWebApplicationContext {
/**
* This initializes the Logger.
*/
private static Log logger = LogFactory.getLog(PreXMLWebApplicationContext.class);
protected String[] getDefaultConfigLocations() {
String environment = System.getProperty("envProperty");
String webirConfig = System.getProperty("webirConfig");
String fi = System.getProperty("FI");
String preHostConfiguration =null;
logger.info("The environment is "+environment);
logger.info("The webirConfig is "+webirConfig);
logger.info("The fi is "+fi);
if(environment != null && webirConfig != null && fi != null) {
preHostConfiguration = DEFAULT_CONFIG_LOCATION_PREFIX +
"classes/applicationContext" + "_" + fi.toUpperCase() +
DEFAULT_CONFIG_LOCATION_SUFFIX;
}
return new String[]{DEFAULT_CONFIG_LOCATION, preHostConfiguration};
}
/**
* This is close API.
*
* #see org.springframework.context.support.AbstractApplicationContext
* #close()
*/
public void close() {
this.doClose();
logger.info("Login-->into the closed");
}
}
<property name="userDelegate" ref="userDelegate" />
name is the field name in your class. When name is userDelegate, it means that WIRAdminBaseAction has a field named userDelegate (and probably a setter setUserDelegate())
ref is the bean name you want to set this field to. In your example, you should have another bean, named userDelegate or bmoUserDelegate which should be set as userDelegate in WIRAdminBaseAction.
So if you want to use the second configuration:
You just need to create a bean with id bmoUserDelegate:
<bean id="bmoUserDelegate" class="mypackage.BmoUserDelegateClass"/>
I am trying to implement a Session-Per-Conversation pattern in a JSF2-Spring-Hibernate Web App so I need my AnnotationSessionFactoryBean to build a Hibernate SessionFactory with a custom CurrentSessionContext class.
I have been receiving this error log:
org.springframework.dao.DataAccessResourceFailureException: Could not obtain Hibernate-managed Session for Spring-managed transaction; nested exception is org.hibernate.HibernateException: No CurrentSessionContext configured!
Here is my xml config for the whole data context used.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="initialSize" value="${datasource.poolInitialSize}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${org.hibernate.dialect.dialectmysqlInno}</prop>
<prop key="hibernate.hbm2ddl.auto">${org.hibernate.ddl.mode}</prop>
<prop key="hibernate.search.default.directory_provider">${org.hibernate.search.directoryprovidr}</prop>
<prop key="hibernate.current_session_context_class">
mx.gob.jgtjo.apps.schedule.web.conversation.ConversationalCurrentSessionContext
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
<property name="hibernateManagedSession" value="true" />
</bean>
<tx:annotation-driven order="0" transaction-manager="transactionManager" />
<context:component-scan base-package="mx.gob.jgtjo.apps.schedule.dao.hibernate" />
</beans>
Also, here is my hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="jgtjoSessionFactory">
<!--Entity -->
<mapping class="mx.gob.jgtjo.apps.schedule.model.AudienciaOral" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.CausaPenal" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.DefensorPenal" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Delito" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.EventoAudiencia" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Juez" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.MinisterioPublico" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.ParteMaterial" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Sala" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.TipoAudiencia" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.User" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Rol" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.DelitoConfigurado" />
</session-factory>
</hibernate-configuration>
As you can see, nothing tricky with hibernate xml.
Why I keep getting this exception?
java.lang.NoSuchMethodException: mx.gob.jgtjo.apps.schedule.web.conversation.ConversationalCurrentSessionContext.<init>(org.hibernate.engine.SessionFactoryImplementor)
It seems that hibernate looks for a constructor in my class that has a SessionFactory as argument.
This is the code from Hibernate which attempts to build the current session context using whatever value you passed in using the hibernate.current_session_context_class property:
private CurrentSessionContext buildCurrentSessionContext() {
String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
// for backward-compatability
if ( impl == null && transactionManager != null ) {
impl = "jta";
}
if ( impl == null ) {
return null;
}
else if ( "jta".equals( impl ) ) {
if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
}
return new JTASessionContext( this );
}
else if ( "thread".equals( impl ) ) {
return new ThreadLocalSessionContext( this );
}
else if ( "managed".equals( impl ) ) {
return new ManagedSessionContext( this );
}
else {
try {
Class implClass = ReflectHelper.classForName( impl );
return ( CurrentSessionContext ) implClass
.getConstructor( new Class[] { SessionFactoryImplementor.class } )
.newInstance( new Object[] { this } );
}
catch( Throwable t ) {
log.error( "Unable to construct current session context [" + impl + "]", t );
return null;
}
}
}
As you can see acceptable values are jta, thread, managed.
Since you're using Spring's transaction management functionality you shouldn't set this property at all. Spring will take care of this for you.
You just need to annotate your transactional methods with #Transactional and a session will be opened and bound to the current thread for you.
Ok, as the anwer above showed me the code and the logging I showed in my question edit the implementation of the CurrentSessionContext interface must have a public constructor with a sessionFactory as argument.
Hibernate docs never say anything like that.
and here is my class:
package mx.gob.jgtjo.apps.schedule.web.conversation;
import javax.servlet.http.HttpServletRequest;
import mx.gob.jgtjo.apps.schedule.web.utils.JsfUtils;
import org.hibernate.HibernateException;
import org.hibernate.classic.Session;
import org.hibernate.context.CurrentSessionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConversationalCurrentSessionContext implements CurrentSessionContext {
private static final long serialVersionUID = 803157986557235023L;
protected static final Logger log = LoggerFactory
.getLogger(ConversationalCurrentSessionContext.class);
public ConversationalCurrentSessionContext() {
}
#Override
public Session currentSession() throws HibernateException {
HttpServletRequest request = null;
try {
request = JsfUtils.getCurrentHttpRequest();
} catch (Exception e) {
log.debug("No current http request in faces context, returning default conversation.");
}
if (request == null) {
return (Session) ConversationManager.getDefaultConversationSession();
} else {
return (Session) ConversationManager.getSessionForRequest(request);
}
}
}
As you can see, I lack that constructor.