Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    MySQL TypeMismatchException java.lang.Integer, got class java.lang.Long

    I tried to setup a test using mysql as a datasource using the OrmDatasource example (only renamed the class to HibernateDS).

    I can show the result (using the fetch) - and can add new records !

    When i try to make an update or an remove i get the exception below !
    Where do i need to change that conversion - as in Hibernate and in the Datasource everything is configured as "int" - where is the "long" comming from ?


    Code:
    2010-01-22 00:21:58,930 [l0-5] DEBUG RPCManager - Request #1 (DSRequest) payload: {
        criteria:{
            ID:1,
            admin:false,
            firstname:"xxxxx",
            lastname:"xxxxx",
            loginname:"xxxxx",
            version:0,
            _selection_4:true
        },
        operationConfig:{dataSource:"users", operationType:"remove"},
        appID:"builtinApplication",
        operation:"users_remove",
        oldValues:{
            ID:1,
            admin:false,
            firstname:"xxxxx",
            lastname:"xxxxx",
            loginname:"xxxxx",
            version:0,
            _selection_4:true
        }
    }
    === 2010-01-22 00:21:58,930 [l0-5] INFO  IDACall - Performing 1 operation(s)
    === 2010-01-22 00:21:58,930 [l0-5] DEBUG DataSource - Creating instance of DataSource 'users'
    === 2010-01-22 00:21:58,930 [l0-5] DEBUG AppBase - [builtinApplication.users_remove] No userTypes defined, allowing anyone access to all operations for this application
    === 2010-01-22 00:21:58,930 [l0-5] DEBUG AppBase - [builtinApplication.users_remove] No public zero-argument method named '_users_remove' found, performing generic datasource operation
    [DEBUG] Loading the Hibernate DS
    === 2010-01-22 00:21:58,937 [l0-5] WARN  RequestContext - dsRequest.execute() failed: 
    org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.amergy.cmt.client.server.customds.SimpleUser. Expected: class java.lang.Integer, got class java.lang.Long
    	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:109)
    	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
    	at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
    	at com.amergy.cmt.client.server.customds.HibernateDS.executeRemove(HibernateDS.java:189)
    	at com.isomorphic.datasource.DataSource.execute(DataSource.java:802)
    	at com.amergy.cmt.client.server.customds.HibernateDS.execute(HibernateDS.java:60)
    	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:708)
    	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:665)
    	at com.isomorphic.application.AppBase.execute(AppBase.java:498)
    	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1175)
    	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:155)

    My class is my SimpleUser
    Code:
    public class SimpleUser implements Serializable{
            private int ID;
    	private int version;
    	private String firstname;
    	private boolean admin = false;
    	private String lastname;
    	private String loginname;
    --------------getters and setters --------------------
    }
    The datasource is defined like this:

    Code:
    	<fields>
    		<field name="ID" type="sequence" primaryKey="true"/>
    		<field name="firstname" type="text" lentght="255" />
    		<field name="admin" typ="boolean"/>
    		<field name="lastname" type="text" length="255"/>
    		<field name="loginname" type="text" length="255"/>
            </fields>
    The hibernate file for that entity looks like that:

    Code:
       <class name="com.amergy.cmt.client.server.customds.SimpleUser" table="SIMPLEUSER" lazy="false">
            <id name="ID" type="int">
                <column name="ID" />
                <generator class="native"></generator>
            </id>
            <version name="version" type="int">
                <column name="version" not-null="true" />
            </version>
    -----------and all the other fields from the entity -------------

    #2
    I tried to narrow it down - and the Long comes from this code line (in the Update part):

    Code:
    Serializable id = (Serializable) req.getFieldValue(primaryKey);
    In the debugger this shows to be an long - but in the database its an int !

    Comment


      #3
      Long is just the default server-side representation of JavaScript's Number.

      The ORM sample is a bit simplified relative to the real Hibernate connector. If your bean declares whole number fields as anything other than Long, you will need to do conversion.

      One way to do it is to create an instance of the target bean via reflection, apply dsRequest.values() to it via DataTools.setProperties() and get the values back via DataTools.getProperties(). At that point all values will have been automatically converted to the target type.

      Comment


        #4
        Thanks for the quick answer !
        I thought thats the reason why i need to define the Datasource .xml file ??

        I am not completely shure if i understood correctly - so you mean to make a reflection of (all) records - or is one enough ?

        How to use the DataTools (i couldnt find them in the javadoc) - and to which object should i assign my values (to the record??)

        Sorry for those many questions - and thanks for the very quick (and patient) support !

        Comment


          #5
          So i have my PropertyDescriptions - but what to do with the DataTools ??

          Code:
          	        List sortBy = req.getSortByFields();
          	        for (Iterator i = sortBy.iterator(); i.hasNext();) {
          	            String sortByField = (String) i.next();
          	            if (sortByField.startsWith("-")) {
          	                // leading minus means sort in descending order
          	                criteria.addOrder(Order.desc(sortByField.substring(1)));
          	            } else {
          	                criteria.addOrder(Order.asc(sortByField));
          	            }
          	        }
          
          	        Class theEntityClass = Class.forName(entityName);
          	        Object theEntity = theEntityClass.newInstance();
          	        
          	        PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(theEntityClass);
          	        
          ?????????????? - where to apply those properties ?????????????
          	        
          	        // Run the query
          	        results = criteria.list();
          	        
          	        // if we're not paged, we're returning all rows
          	        if (totalRows == -1) totalRows = results.size();
          	        dsResponse.setTotalRows(totalRows);

          Comment


            #6
            There's separate JavaDoc for server-side APIs, linked from index.html in your SmartGWT Eval package. That's where DataTools and other server-side APIs are explained.

            Comment


              #7
              I use my licensed Pro Version - but i cannot figure out the usage of it !

              I tried something like that:
              Code:
              	        Class theEntityClass = Class.forName(entityName);
              	        Object theEntity = theEntityClass.newInstance();
              	        
              	       Map data = DataTools.getProperties(theEntity);
              
              	       List realResults = null;
              	       
              	       Iterator iterator = results.iterator();
              	       while (iterator.hasNext()){
              	    	   Object obj = iterator.next();
              	    	   Object realObj = DataTools.setProperties(data, obj);
              	    	   realResults.add(realObj);
              	       }
              But this erases all the data - where should i get the real values from - after applying the properties ?

              Comment


                #8
                You don't need to do anything to the results retrieved from Hibernate - just setData() with those.

                You don't need to do anything special for "update" or "add" operations because these already do automatic conversion in the ORM sample code.

                The sole case where you would need to add code to the ORM sample in order to convert types is the criteria of the fetch operation, and the suggested approach is to use a setProperties()/getProperties() cycle with dsRequest.getCriteria() on an instance of target bean, in order to cause automatic type conversion.

                Comment


                  #9
                  Thanks again for the fast reply !
                  The code above is in the fetched function (sorry not to post the whole code) - i only do not see where i need to do the conversion / copy - with the get and setProperties();

                  As you mentioned the req.getCriteris - when i debug the
                  Code:
                   Map rCriteria = req.getCriteria();
                  it has no entries ??

                  Am i missing something ?

                  Comment


                    #10
                    getCriteria() will return the criteria if there are criteria - as in the first request you posted.

                    Comment


                      #11
                      Probably we are talking about different items - see my screenshot showing that the req.getCriteria() is having no result !!
                      Attached Files

                      Comment


                        #12
                        This is getting silly.. please see previous post. getCriteria() will return criteria if criteria were passed from the client. Your first post in this thread showed logs of a request where criteria were in fact passed from the client. If no criteria were passed from the client, getCriteria() will return an empty Map, and this is normal and correct.

                        In your first post you showed an error that only occurs if criteria are present in getCriteria() so you just need to get back to that state.

                        Comment


                          #13
                          Yes thats true - its getting silly !
                          The problem (and these where the logs from) are from an REMOVE or UPDATE (see the logs) - and there criterias are passed from the client to the server !

                          There the problem seems to be - but you where pointing me to the FETCH operation - where no criterias are passed from the server to the client so i cannot make any conversions on them !

                          And in the update method (as you mentioned below) the conversion is not working as i get the same error as on the REMOVE !

                          Comment


                            #14
                            See the docs for getCriteria() : fetch, update and remove all have criteria. In the case of update and remove, the criteria contain the primaryKey value.

                            If you're using an "int" field as the unique ID (which is *highly inadvisable* - use long instead unless you are inheriting code you cannot change - int is too small) then you will need to do type conversion on update and remove as well as fetch.

                            int <-> long type conversion is Java basics you should be able to handle, but again, you can apply the criteria (or any Map) to the target bean via setProperties() and get it back via getProperties() as a means of forcing all values in the Map to conform to the types of the setters on the bean.

                            Comment


                              #15
                              Thanks i now changed the ID to a long - would that also cause troubles on all "number" values ?

                              Comment

                              Working...
                              X