Hi,
I just read the EE showcase datasources, but none of my question about that particular way to work is answered there.
First of all, I don’t understand the logic behind such a datasource. For me, the data coming out the database is managed by a particular framework. I saw your direct SQL examples, and your Hibernate example. For my project I must use the MyBatis framework. I do not understand how to use a datasource wit my custom myBatis requests.
Next, I see that a datasource is linked to a table. Again, it seems then that the datasource communicates directly with the database. How can I configure some custom SQL join (because in this project’s business logic, data displayed comes from 7 differents tables).
I’ve other questions about this, but this two first questions are a good start point.
The best thing to do is read the QuickStart Guide. All of these different scenarios are covered in detail in the chapter on the Smart GWT Server Framework.
In this application, I use an iBatis database connection that is working well. The dummy table used has this DDL :
CREATE TABLE IF NOT EXISTS `client` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nom` varchar(50) NOT NULL,
`password` varchar(256) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `nom` (`nom`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
INSERT INTO `client` (`id`, `nom`, `password`) VALUES
(1, 'Romain', 'testromain'),
(2, 'Ivan', 'machin'),
(3, 'André', 'trucmuche'),
(4, 'Marie-Claire', 'chose');
I wish to make two things with this dummy application:
1- understand why, after having copied the showcase example my application sill doesn’t work,
2- create a server datasource that will connect iBatis threw a java service layer (not directly the ClientDao interface).
First of all, consider why you are using iBatis - SQLDataSource, with it’s SQL templating capability and the built-in ability to generate advanced SQL queries directly from user input, is generally just better. Much less effort for much more functionality.
As far as what problem you’re having, you need to tell us what errors you’re receiving (don’t just upload the project).
Hi,
For the question of iBatis, it’s very simple : it’s a client requirement and we cannot do other. But I think that that is not a problem at all because the java class that implements the DataSource just have to call the iBatis service I wrote and that’s all, am I right ?
For the problem, there is two main problems :
I’ve declared a LOG4J config file. I’ve some output on the FILE appender but the logs says that the FILE appender is not found … That’s not a big issue and it’s more a detail.
When I set the datasource “client” to my listgrid, the application just not loads. I’ve no warn outputs in the log4j file (server side seems to say that everything is ok), no outputs in the tomcat’s logs (except the log4j no appender warn) and no warn outputs in the developper console … I’ve no experience enough with SmartGWT to guess where the problem may come from, for me it may come from everywhere …
It’s not a problem to use iBatis, but it’s much, much easier to use SQLDataSource than to use iBatis. If you already have a large number of services implemented in iBatis that are ready to use, it makes sense to use them via DMI, but it would still make sense to build new functionality with SQLDataSource.
The complete lack of errors in not normal. Be sure you are looking in the hosted mode console within Eclipse as well, your code is probably just crashing.
Thanks, your link helped me to point out two problems. The biggest was the bad datasource path in the script element.
The second is that I only have Pro version and Enterprise is needed to use DMI datasource like I did, so I rewrote the clients.ds.xml file :
But now, when I try to access it, I get this error :
01 Oct 2010 15:50:10,426 ERROR DataSourceLoader:329 - Exception while attempting to load a DataSource
java.lang.UnsatisfiedLinkError: com.smartgwt.client.util.JSOHelper.createObject()Lcom/google/gwt/core/client/JavaScriptObject;
at com.smartgwt.client.util.JSOHelper.createObject(Native Method)
at com.smartgwt.client.core.BaseClass.<init>(BaseClass.java:37)
at com.smartgwt.client.data.DataSource.<init>(DataSource.java:111)
at be.uniway.rvk.test.datasource.server.DMIHandler.<init>(DMIHandler.java:8)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at com.isomorphic.base.Reflection.newInstance(Reflection.java:208)
at com.isomorphic.base.Reflection.newInstance(Reflection.java:202)
at com.isomorphic.datasource.BasicDataSource.fromConfig(BasicDataSource.java:138)
at com.isomorphic.datasource.DataSource.fromConfig(DataSource.java:164)
at com.isomorphic.datasource.FileSystemDSRepo.loadDS(FileSystemDSRepo.java:110)
at com.isomorphic.datasource.DataSource.forName(DataSource.java:147)
at com.isomorphic.datasource.DataSource.forName(DataSource.java:144)
at com.isomorphic.datasource.DataSource.forName(DataSource.java:141)
at com.isomorphic.datasource.PoolableDataSourceFactory.makeUnpooledObject(PoolableDataSourceFactory.java:89)
at com.isomorphic.datasource.PoolableDataSourceFactory.makeObject(PoolableDataSourceFactory.java:96)
at com.isomorphic.pool.PoolManager.borrowObject(PoolManager.java:76)
at com.isomorphic.datasource.DataSourceManager.getDataSource(DataSourceManager.java:56)
at com.isomorphic.servlet.DataSourceLoader.processRequest(DataSourceLoader.java:80)
at com.isomorphic.servlet.DataSourceLoader.doGet(DataSourceLoader.java:64)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
You cannot use GWT / Smart GWT client side code on your server. In this case the you’re trying to construct an instance of the SmartGWT client side com.smartgwt.client.data.DataSource class on the server in DMIHandler which is incorrect. On the server side use com.isomorphic.datasource.DataSource.
I tried with com.isomorphic.datasource.DataSource but it makes a ClassCastException.
I changed it to com.isomorphic.datasource.BasicDataSource and it runs fine now I let you know here if I have other problems
public class DMIHandler extends BasicDataSource {
private ClientDao clientDao = new ClientDaoImpl();
public DMIHandler() {
super();
}
@Override
public DSResponse executeFetch(DSRequest req) throws Exception {
// String userName = (String) req.getAttribute("username");
List<ClientDto> results = null ;
Map c = req.getCriteria();
String userName = null;
if ( c.containsKey("username") ) {
userName = c.get("username").toString();
}
if ( userName != null ) {
ClientDto criteria = new ClientDto(null,userName,null);
results = clientDao.getClientsByCriteria(criteria);
}
if ( results != null ) {
DSResponse response = new DSResponse();
response.setStartRow(0L);
response.setEndRow((results.size())-1);
response.setTotalRows(results.size());
response.setData(results);
} else {
return null;
}
return super.executeFetch(req);
}
@Override
public DSResponse execute(DSRequest req) throws Exception {
if ( "fetch".equalsIgnoreCase(req.getOperation()) || "clients_fetch".equalsIgnoreCase(req.getOperation()) ) {
return this.executeFetch(req);
} else {
return null;
}
}
}
My problem is that I don’t know well how to handle the DSRequest to extract the values stored in it. I create the criteria like this :
searchButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Criteria c = new Criteria();
c.addCriteria("userName",(String) inputUserName.getValue() );
clientsGrid.fetchData(c);
}
});
I suppose (I’ve no source to check my idea) that when the clientsGrid.fetchData(c); is called, an IDA Call is made. Then, the link to my DataSource is done. Here, the execute method is run and finally call my executeFetch method. Am I right ?
public class DMIHandler {
public DSResponse fetch(DSRequest req) {
//Here u can manipulate the search criteria, in other
//words add new criteria, connect them with "and", "or" ..
List criteriaList = new ArrayList();
Map searchMap = new HashMap();
searchMap.put("operator", "equals")
searchMap.put("fieldName", "nom")
searchMap.put("value", "Marie-Claire")
criteriaList.add(searchMap);
//if you want to use a criteria send from the client
Map clientCriteria = req.getCriteria();
criteriaList.add(clientCriteria)
Map criteriaMap = new LinkedHashMap<String, Object>();
criteriaMap.put("operator", "and");
criteriaMap.put("_constructor", "AdvancedCriteria");
criteriaMap.put("criteria", criteriaList);
req.setCriteria(criteriaMap);
DSResponse response = req.execute();
return response;
Ok, now the listgrid of this dummy project works well.
I try now to integrate the XLS export but I get this error :
05 Oct 2010 09:37:17,713 INFO RequestContext:388 - URL: '/datasource/smartgwtserverdatasource/sc/IDACall/Results.xls/Results.xls', User-Agent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3': Safari with Accept-Encoding header
05 Oct 2010 09:37:17,728 INFO IDACall:388 - Performing 1 operation(s)
05 Oct 2010 09:37:17,837 INFO DSResponse:388 - [builtinApplication.clients_fetch] DSResponse: List with 1 items
05 Oct 2010 09:37:18,164 ERROR IDACall:329 - Error executing operation: clients_fetch
java.lang.ClassCastException: be.uniway.rvk.test.datasource.shared.ClientDto cannot be cast to java.util.Map
at com.isomorphic.rpc.ExcelDataExport.export(ExcelDataExport.java:137)
at com.isomorphic.rpc.ExcelDataExport.exportResultSet(ExcelDataExport.java:73)
at com.isomorphic.rpc.DataExport.exportResultSet(DataExport.java:311)
at com.isomorphic.rpc.RPCManager.completeResponse(RPCManager.java:890)
at com.isomorphic.rpc.RPCManager.send(RPCManager.java:574)
at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:130)
at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:95)
at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
05 Oct 2010 09:37:18,164 ERROR IDACall:329 - Top-level servlet error:
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map
at com.isomorphic.rpc.ExcelDataExport.export(ExcelDataExport.java:137)
at com.isomorphic.rpc.ExcelDataExport.exportResultSet(ExcelDataExport.java:73)
at com.isomorphic.rpc.DataExport.exportResultSet(DataExport.java:311)
at com.isomorphic.rpc.RPCManager.completeResponse(RPCManager.java:890)
at com.isomorphic.rpc.RPCManager.send(RPCManager.java:574)
at com.isomorphic.rpc.RPCManager.sendFailure(RPCManager.java:657)
at com.isomorphic.rpc.RPCManager.sendFailure(RPCManager.java:678)
at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:136)
at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:95)
at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
For reminder, the actual code called is in attachement.
If you need anything else, just let me know.
Executing this line after my setData() generates an error (setData called on a DSResponse with no datasource) so I created a List<Map> with the property name as key, and the export works well too now.
A new question for you : is it possible to overwrite the listgrid’s criteria for the export ?