Announcement

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

    TreeGrid + JPA DataSource and inserting nodes into an empty tree

    I'm trying to use a JPA datasource to populate a TreeGrid. I'm obviously not getting something even after reading the various JavaDocs for TreeGrid, Tree, DataSource, and TreeDataBinding.

    So my first questions was how best to add nodes to the tree using my JPA DataSource. I presumed that I should use the addData() method on the data source to do this. If not, then I need to go back and start over.

    My next problem came when trying to deal with my JPA and its ManyToOne relationship between the node and its parent node. All of my attempts to use the actual node objects (i.e. datasource records) failed and searching through the forums led me to believe that I need to use a parentId instead. So I reworked things to do that, including adding a hack to my JPA bean to include a parentId and not just a reference to a parent object along with some annotations so that it would share the same database Id column between the parent field/object and the parentId field.

    My next problem then came with how to create the initial node if there is no parentId. I chose a variety of values to no avail. I've used null and avoided some errors but not others (like null pointer exceptions in the server). I've used 0 with a different set of exceptions (null pointer and number format exceptions).

    So I know someone must have succeeded here, but I'm just failing. No matter what I seem to do, I end up with a record in the database with a correct id, a correct name, and a null parentId.

    BTW, this is all on the latest GWT 2.3 and SmartGWT EE eval.

    Here's my JPA (removed the setters/getters):

    Code:
    @Entity
    @Table(name = "T_DOMAIN")
    public class Domain {
    	@Id
    	@GeneratedValue(strategy = IDENTITY)
    	@Column(nullable = false)
    	private long id;
    	@Basic
    	private String name;
    	@OneToMany(mappedBy = "domain")
    	private Collection<DomainManaged> domainManaged;
    	@ManyToOne(fetch = LAZY, optional = true)
            @JoinColumn(name = "parentDomainId", referencedColumnName = "parentDomainId", nullable=false, insertable=false, updatable=false)
    	private Domain parentDomain;
    	@OneToMany(mappedBy = "parentDomain")
    	private Collection<Domain> subDomains;
            private Long parentDomainId;
    And here's the data source xml:

    Code:
    <DataSource
        ID="domain_DataSource"
        serverConstructor="com.isomorphic.jpa.JPADataSource"
        beanClassName="mobi.droidcloud.mgmt.model.Domain"
        dropExtraFields="true"    
        >
        <fields>
            <field name="id"    type="sequence" hidden="true"   primaryKey="true" />
            <field name="name"  type="text"     title="Name"    required="true"   />
            <field name="parentDomainId" type="int"  title="Parent Domain Id" canEdit="false" 
            	foreignKey="id" rootValue="0" />
        </fields>
    </DataSource>
    And now most of the Java code:

    Code:
        public void onModuleLoad() {
    	KeyIdentifier debugKey = new KeyIdentifier();
    	debugKey.setCtrlKey(true);
    	debugKey.setKeyName("D");
    
    	Page.registerKey(debugKey, new KeyCallback() {
    		public void execute(String keyName) {
    			SC.showConsole();
    		}
    	});
    
            VStack vStack = new VStack();
            vStack.setTop(50);
            vStack.setWidth("100%");
            vStack.setMembersMargin(20);
    
            final TreeGrid treeGrid = new TreeGrid();
            treeGrid.setWidth(500);
            treeGrid.setHeight(250);
            
            final DataSource domainDS = DataSource.get("domain_DataSource");
            treeGrid.setTreeRootValue(0);
            domainDS.fetchData(new Criteria("name", "Global"), new DSCallback() {
    		@Override
    		public void execute(DSResponse response, Object rawData,
    				DSRequest request) {
    			if (response.getTotalRows() == 0) {
    				Record r = new Record();
    				r.setAttribute("name", "Global");
    				r.setAttribute("parentDomainId", new Long(0)); // (Long)null);
    				domainDS.addData(r, new DSCallback() {
    					@Override
    					public void execute(DSResponse resp, Object data,
    							DSRequest req) {
    						if (resp.getTotalRows() != 1) {
    							System.out.println("Unexpected response after adding the global node");
    						}
    					}
    				});
    			}
    		}
            });
      
            TreeGridField nameField = new TreeGridField("name");
            nameField.setTreeField(true);
            treeGrid.setFields(nameField);
            treeGrid.setDataSource(domainDS);
            treeGrid.setAutoFetchData(true);
    	treeGrid.setCanEdit(true);
    	treeGrid.setCanAcceptDroppedRecords(true);
            
            IButton newDomainButton = new IButton("New Domain");
            newDomainButton.addClickHandler(new ClickHandler()
            {
                public void onClick (ClickEvent event)
                {
                    final ListGridRecord r = treeGrid.getSelectedRecord();
                    if (r != null) {
                    	Record newDomain = new Record();
                    	newDomain.setAttribute("name", "new-domain");
                    	newDomain.setAttribute("parentDomainId", r.getAttributeAsInt("id"));
    //                	newDomain.setAttribute("parentDomainId", r);
                    	domainDS.addData(newDomain, new DSCallback() {
    						@Override
    						public void execute(DSResponse response,
    								Object rawData, DSRequest request) {
    		                	Tree t = treeGrid.getData();
    		                	if (!t.isOpen((TreeNode)r)) {
    		                		// open parent node to show the new node
    		                		t.openFolder((TreeNode)r);
    		                	}
    						}
                    	});                	
                    } else {
                    	// new top-level domain
    					Record record = new Record();
    					record.setAttribute("name", "new-domain");
    					System.out.println("Assigning a global with a parentId of 1 (cheating)");
    					record.setAttribute("parentDomainId", new Long(0)); //(Long)null);
                    	domainDS.addData(record, new DSCallback() {
    						@Override
    						public void execute(DSResponse response,
    								Object rawData, DSRequest request) {
    						}
                    	});
                    }
                }
            });
            IButton rmDomainButton = new IButton("Delete Domain");
            rmDomainButton.addClickHandler(new ClickHandler()
            {
                public void onClick (ClickEvent event)
                {
                    ListGridRecord r = treeGrid.getSelectedRecord();
                    if (r != null) {
                    	domainDS.removeData(r);
                    }
                }
            });
    
    
            IButton adminButton = new IButton("Admin Console"); adminButton.addClickHandler(new ClickHandler() {
            	public void onClick(ClickEvent event) { com.smartgwtee.tools.client.SCEE.openDataSourceConsole();
            	} });
            IButton dsGeneratorButton = new IButton("DS Generator"); dsGeneratorButton.addClickHandler(new ClickHandler() {
            	public void onClick(ClickEvent event) { com.smartgwtee.tools.client.SCEE.openDataSourceGenerator();
            	} });
            vStack.addMember(treeGrid);
            vStack.addMember(newDomainButton);
            vStack.addMember(rmDomainButton);
            vStack.addMember(adminButton);
            vStack.addMember(dsGeneratorButton);
    
            vStack.draw();
        }

    #2
    No, addData() is no the right approach.

    The involvement of JPA ends at the client-server boundary. Get the right IDs and parentIds in the returned data as shown in the Developer Console's RPC tab and it works.

    Comment


      #3
      Originally posted by Isomorphic View Post
      No, addData() is no the right approach.

      The involvement of JPA ends at the client-server boundary. Get the right IDs and parentIds in the returned data as shown in the Developer Console's RPC tab and it works.
      Ok, so I'm a bit confused. When I look in the Developer Console's RPC tab, I'm not seeing anything that says "don't use addData".

      In fact, I was still using addData() but not using the hacks to the JPA to add a special domainParentId field to the JPA annotations. I did this by following directions from someone in the forums.

      When I pull those things out, I just use my parentDomain objects (and pass the Ids), I at least see things end up in the database the correct way. Of course, I'm still using addData() (either directly using the DataSource or via the TreeGrid).

      I've seen lots of articles in the forum on trees. I saw one with this quote from Isomorphic:

      addData() is an operation for databound TreeGrids (TreeGrids with a DataSource). If you want to add nodes to a non-databound TreeGrid, call methods on the Tree directly.
      So if addData() is not the right approach to adding nodes to databound tree grid, what is?

      I'd include the warning/errors messages I see, but they may be moot if I can get past this addData() question.

      Comment


        #4
        addData() is an operation on a DataSource which adds a new Record to permanent storage. If that's what you are trying to do, use addData().

        If what you are trying to do is *populate* a TreeGrid with pre-existing data, addData() is not the correct approach. Instead you need to focus on setting up your DataSource to return correct id an parentId field values.

        Comment


          #5
          Originally posted by Isomorphic View Post
          addData() is an operation on a DataSource which adds a new Record to permanent storage. If that's what you are trying to do, use addData().

          If what you are trying to do is *populate* a TreeGrid with pre-existing data, addData() is not the correct approach. Instead you need to focus on setting up your DataSource to return correct id an parentId field values.
          I think I get that. So I am trying to do both. I have a TreeGrid. I want to display its contents from a JPA defined data source. I want to be able to add new nodes to said tree by selecting a node and then clicking on a button, menu, etc that says "add new folder/thingie" which results in a new folder being added to the database as well as showing up in the tree.

          I am running into several problems. First, my database starts out empty. When the app starts up and sees that there is no tree node named "Global", it adds one. Right now, it adds one using addData(). I've used the method on the datasource and on the treegrid that is populated from the datasource. When I create that initial "Global" record, it doesn't have a "parentId". So to add it, I have tried using "null" as well as an id of 0. If I use 0, I will get a warning that says that it can't find an entity with an Id of 0, so it sets the parentId to null. When the treegrid gets its updated results from the server, it appears to choke on this null and refuses to draw the contents of the treegrid. I see an empty treegrid with a message "no items to show".

          I I reload the page/app from the browser, this time the app sees that there is a Global entity and it happily renders the tree with the Global node. Looking at the various output in the logs, I see: Value '0' of type 'class java.lang.Long' can not be casted to type 'class mobi.droidcloud.mgmt.model.Domain'.

          This is likely due to a mismatch in the types - my parent reference is to type Domain, but the lookups via the datasource need the ids instead of the actual JPA object. In any case, there are a few "null pointers" being ignored warnings, but then the actual "Global" node does show up in the tree grid. I do see it in the database as well, although the parentId in the database table is null and not 0.

          If I click on that node and try to "open" the folder, it will redraw itself with an empty tree (no items to show message). Looking at the errors, it shows one error similar to above: "Failed to cast value for field 'parentDomain'. Value '1' of type 'class java.lang.Long' can not be casted to type 'class mobi.droidcloud.mgmt.model.Domain'." as well as the following: WARN DataSource - Couldn't get value for property 'parentDomain' for datasource 'domain_DataSource' - ignoring. Actual error: java.lang.NullPointerException

          I can continue by refreshing. I can add sub-nodes to the Global node as long as I don't open any leaf nodes. I don't see any errors. When one of these folder nodes is open, that is when I see errors. In addition to the null pointer exceptions mentioned above, I also get the following:
          WARN DataSource - Couldn't get value for property 'parentDomain' for datasource 'domain_DataSource' - ignoring. Actual error: java.lang.NullPointerException.

          So when I tried to work around these, I found some older articles where people were changing the JPA to include a special parentId field and map that to the same column as the manytoone parent object field. The example code I put in the original post includes those changes. They didn;t work at all. I found I had the same issues creating the initial node (couldn't add a node with a 0 as a parentId). And I could never render anything in the treegrid - it was always empty.

          BTW, the code I was trying to get working before adding the parentId hack via the web site is the following:

          Code:
              public void onModuleLoad() {
          		KeyIdentifier debugKey = new KeyIdentifier();
          		debugKey.setCtrlKey(true);
          		debugKey.setKeyName("D");
          
          		Page.registerKey(debugKey, new KeyCallback() {
          			public void execute(String keyName) {
          				SC.showConsole();
          			}
          		});
          
                  VStack vStack = new VStack();
                  vStack.setTop(50);
                  vStack.setWidth("100%");
                  vStack.setMembersMargin(20);
          
                  final TreeGrid treeGrid = new TreeGrid();
                  treeGrid.setWidth(500);
                  treeGrid.setHeight(250);
                  
                  final DataSource domainDS = DataSource.get("domain_DataSource");
            
                  TreeGridField nameField = new TreeGridField("name");
                  nameField.setTreeField(true);
                  treeGrid.setFields(nameField);
          	treeGrid.setCanEdit(true);
          	treeGrid.setCanAcceptDroppedRecords(true);
                  treeGrid.setTreeRootValue(0);
                  treeGrid.setDataSource(domainDS);
                  treeGrid.setAutoFetchData(true);
                  
                  treeGrid.fetchData(new Criteria("name", "Global"), new DSCallback() {
          		@Override
          		public void execute(DSResponse response, Object rawData,
          			DSRequest request) {
          			if (response.getTotalRows() == 0) {
          				Record r = new Record();
          				r.setAttribute("name", "Global");
          				r.setAttribute("parentDomain", 0);
          				treeGrid.addData(r, new DSCallback() {
          					@Override
          					public void execute(DSResponse resp, Object data,
          							DSRequest req) {
          						if (resp.getTotalRows() != 1) {
          							System.out.println("Unexpected response after adding the global node");
          						}
          					}
          				});
          			}
          		}
                  });
                  
                  IButton newDomainButton = new IButton("New Domain");
                  newDomainButton.addClickHandler(new ClickHandler()
                  {
                      public void onClick (ClickEvent event)
                      {
                          final ListGridRecord r = treeGrid.getSelectedRecord();
                          if (r != null) {
                          	Record newDomain = new Record();
                          	newDomain.setAttribute("name", "new-domain");
          //                	newDomain.setAttribute("parentDomainId", r.getAttributeAsInt("id"));
                          	newDomain.setAttribute("parentDomain", r.getAttributeAsInt("id"));
                          	treeGrid.addData(newDomain, new DSCallback() {
          						@Override
          						public void execute(DSResponse response,
          								Object rawData, DSRequest request) {
          		                	Tree t = treeGrid.getData();
          		                	if (!t.isOpen((TreeNode)r)) {
          		                		// open parent node to show the new node
          		                		t.openFolder((TreeNode)r);
          		                	}
          						}
                          	});                	
                          } else {
                          	// new top-level domain
          					Record record = new Record();
          					record.setAttribute("name", "new-domain");
          					System.out.println("Assigning a global with a parentId of 1 (cheating)");
          					record.setAttribute("parentDomain", 0);
                          	treeGrid.addData(record, new DSCallback() {
          						@Override
          						public void execute(DSResponse response,
          								Object rawData, DSRequest request) {
          						}
                          	});
                          }
                      }
                  });
                  IButton rmDomainButton = new IButton("Delete Domain");
                  rmDomainButton.addClickHandler(new ClickHandler()
                  {
                      public void onClick (ClickEvent event)
                      {
                          ListGridRecord r = treeGrid.getSelectedRecord();
                          if (r != null) {
                          	treeGrid.removeData(r);
                          }
                      }
                  });
          
          
                  IButton adminButton = new IButton("Admin Console"); adminButton.addClickHandler(new ClickHandler() {
                  	public void onClick(ClickEvent event) { com.smartgwtee.tools.client.SCEE.openDataSourceConsole();
                  	} });
                  IButton dsGeneratorButton = new IButton("DS Generator"); dsGeneratorButton.addClickHandler(new ClickHandler() {
                  	public void onClick(ClickEvent event) { com.smartgwtee.tools.client.SCEE.openDataSourceGenerator();
                  	} });
                  vStack.addMember(treeGrid);
                  vStack.addMember(newDomainButton);
                  vStack.addMember(rmDomainButton);
                  vStack.addMember(adminButton);
                  vStack.addMember(dsGeneratorButton);
          
                  vStack.draw();
          
              }
          The datasource xml:
          Code:
          <DataSource
              ID="domain_DataSource"
              serverConstructor="com.isomorphic.jpa.JPADataSource"
              beanClassName="mobi.droidcloud.mgmt.model.Domain"
              dropExtraFields="true"    
              >
              <fields>
                  <field name="id"    type="sequence" hidden="true"   primaryKey="true" />
                  <field name="name"  type="text"     title="Name"    required="true"   />
                  <field name="parentDomain" type="int"  title="Parent Domain Id" canEdit="false" 
                  	foreignKey="id" rootValue="0" />
          <!--         <field name="parentDomainName" includeFrom="domain_DataSource.name" title="Parent Domain" /> -->
              </fields>
          </DataSource>
          And the JPA annotated bean:
          Code:
          @Entity
          @Table(name = "T_DOMAIN")
          public class Domain {
          	@Id
          	@GeneratedValue(strategy = IDENTITY)
          	@Column(nullable = false)
          	private long id;
          	@Basic
          	private String name;
          	@OneToMany(mappedBy = "domain")
          	private Collection<DomainManaged> domainManaged;
          	@ManyToOne(fetch = LAZY, optional = true)
          	private Domain parentDomain;
          	@OneToMany(mappedBy = "parentDomain")
          	private Collection<Domain> subDomains;
          }

          Comment


            #6
            Oh, and it may not be clear. When I add in a parentDomainId field to my JPA object and use that in my client code to addData and to fetch the tree, the issues I have seem to come down to how to create the first node.

            In particular, using addData() with a record that has my "name" field and a parentDomainId field of 0, results in an error being returned claiming that there is no object with an Id 0 for the parent object and it was setting the value to null (I see that in the DB). I then see an null reference exception trying to access the parentDomainId field (which was changed to null). The tree then fails to load anything.

            If I choose to provide a null value for the parentDomainId in the record provided to addData(), I do not get the error trying to get a parent object, but do get the null reference exception trying to access the parentDomainId. It also does not render anything in the treegrid.

            Comment


              #7
              Root-level nodes (no parent) should have as their parentId whatever value you have set for dataSourceField.rootValue. You can set this to whatever you want, but we recommend setting it to something other than null, which can be ambiguous with bad data.

              Comment


                #8
                Originally posted by Isomorphic View Post
                Root-level nodes (no parent) should have as their parentId whatever value you have set for dataSourceField.rootValue. You can set this to whatever you want, but we recommend setting it to something other than null, which can be ambiguous with bad data.
                Well that is the "root" of the matter. I have not been able to set it to any value. Setting it to 0 or 1 or anything else results in an error when doing the insert (no entity with that id exists, setting parent to null warning message). And once there is a null for the parentId in the database, the TreeGrid just refuses to draw a tree (exception/warning: Couldn't get value for property 'parentDomainId' for datasource 'domain_DataSource' - ignoring. Actual error: java.lang.NullPointerException).

                I spent a few more hours on this again today and think I have it all working/figured out. Here are the accumulation of my errors and what I had to do to get it to work (for anyone else who trips on this):

                1) I had to add a parentDomainId field of type Integer (int did not work) to mirror my @ManyToOne parentDomain field. So the following was added to my JPA bean:
                Code:
                	// added field/column below
                	@Column(name = "parentDomain", nullable=true)
                	private Integer parentDomainId;
                	// original field/column below
                	@ManyToOne(fetch = LAZY, optional = true)
                	@JoinColumn(name = "parentDomain", nullable=true, insertable=false, updatable=false)
                2) I had to set the root value to null (against recommendation). You must do this programmatically using treeGrid.setTreeRootValue((Integer)null); - I could not figure out how to set it in the datasource xml file - and when it was in there, it seems to override the value set in the code.

                3) When adding the first node (or any node without a parent), I had to explicitly set the parentDomainId field to a null Integer value. e.g.:
                Code:
                	record.setAttribute("parentDomainId", (Integer)null);
                4) To get around a NumberFormatException, you MUST use a properly capitalized type value, meaning type="Integer" and not type="int" or type="integer". The capital 'I' is required.
                <field name="parentDomainId" type="Integer" title="Parent Domain Id" canEdit="false"
                foreignKey="id" />

                Comment


                  #9
                  type="Integer" is not the name of any built-in type (see docs) so what your code is actually doing is declaring a custom type, and without any further declarations your field is being treated as type="text". This should not be necessarily in your current solution and probably appeared necessary while you still had other issues.

                  Although we recommend setting it to non-null, the default rootValue is effectively null, so you can just remove that declaration / code entirely.

                  When you use a rootValue that isn't null with a JPA field of type int or Integer, as you saw, JPA will reject any kind of marker value like 0 or 1 if there's no such entity. There are a couple of approaches here:

                  1. create a JPA entity to serve as the official root entity.

                  2. add getters and setters for parentIdField without adding any JPA declarations, so that calls to getParentIdField() on a root level entity return the rootValue, and setParentIdField(rootValue) sets the relation to null / unlinked.

                  Comment


                    #10
                    Originally posted by Isomorphic View Post
                    type="Integer" is not the name of any built-in type (see docs) so what your code is actually doing is declaring a custom type, and without any further declarations your field is being treated as type="text". This should not be necessarily in your current solution and probably appeared necessary while you still had other issues.
                    Hmmm. If I remove this type attribute completely, I now get the numberformatexception. And the way to get around that was to switch the rootValue to be some int value, which results in the JPA initial insertion issue.

                    Originally posted by Isomorphic View Post
                    Although we recommend setting it to non-null, the default rootValue is effectively null, so you can just remove that declaration / code entirely.

                    When you use a rootValue that isn't null with a JPA field of type int or Integer, as you saw, JPA will reject any kind of marker value like 0 or 1 if there's no such entity. There are a couple of approaches here:

                    1. create a JPA entity to serve as the official root entity.
                    I never could figure out how to do this without me writing some SQL on the side to insert such a node in the database. The hibernate/JPA code rejected it because there was no parent.

                    Originally posted by Isomorphic View Post
                    2. add getters and setters for parentIdField without adding any JPA declarations, so that calls to getParentIdField() on a root level entity return the rootValue, and setParentIdField(rootValue) sets the relation to null / unlinked.
                    Seems a bit contrived. Not sure how this would impact any of the server side JPA logic not used in my UI. Perhaps not at all.

                    And what exactly is the issue if you use null as the rootValue? I know that it isn't recommended, but a null parent is a common way to denote root nodes in trees in a typical programming data structure.

                    Comment


                      #11
                      Hmmm. If I remove this type attribute completely, I now get the numberformatexception. And the way to get around that was to switch the rootValue to be some int value, which results in the JPA initial insertion issue.
                      You haven't shown the NumberFormatException so we couldn't tell you its actual cause.

                      I never could figure out how to do this without me writing some SQL on the side to insert such a node in the database. The hibernate/JPA code rejected it because there was no parent.
                      That doesn't make much sense, didn't you just indicate you are now successfully using nodes that have parentId = null? If so, use the same approach to save a root node.

                      Seems a bit contrived. Not sure how this would impact any of the server side JPA logic not used in my UI. Perhaps not at all.
                      Not at all, unless they call the setter. To the extent this is contrived, it's because JPA tries to make certain relations "implicit". This works OK in all Java system but falls down any time data needs to be communicated to other systems.

                      And what exactly is the issue if you use null as the rootValue? I know that it isn't recommended, but a null parent is a common way to denote root nodes in trees in a typical programming data structure.
                      You create ambiguity between null meaning unset and null meaning intentionally has no parent.

                      Comment


                        #12
                        Originally posted by Isomorphic View Post
                        You haven't shown the NumberFormatException so we couldn't tell you its actual cause.
                        Sorry, I thought I had covered that. The numberformatexception occurred most recently when I was using null for the tree root and had either (a) set the type in the .ds.xml file to anything other than Integer or (b) left the type=Integer out of the ds.xml file altogether.

                        I could get rid of the numberformatexception by switching my root to be 0 or some other integer, but then Hibernate/JPA would prevent the object from being added properly because there was no object/record with that id in the DB (that would require some code added to the parent getter and setter as you suggested).

                        It had happened earlier in my debugging when I was trying to figure out how to use the "parentDomain" field instead of adding a special parentDomainId field of type int to my JPA bean. Switching to a new field of type int that shared the column with the parentDomain object reference solved that issue.

                        So if I am finally getting this, it would seem I can choose between adding special logic in my JPA for handling tree root issues or potentially introduce some ambiguity around a null parentId.

                        Originally posted by Isomorphic View Post
                        You create ambiguity between null meaning unset and null meaning intentionally has no parent.
                        unset == no parent. If not, then shame on me if that happened :-)

                        Now, on to my second experiment in my EE eval - JPA inheritance (both SINGLE_TABLE and JOIN_TABLE types).
                        Last edited by bjvetter; 23 Jul 2012, 13:28.

                        Comment


                          #13
                          Just to reiterate: type="Integer" is not a special value. It has the same meaning as type="regetnI".

                          As far as the NumberFormatException, it sounds like you already have a solution, but we would need actual diagnostic information to help. We don't even know if you mean a client or server exception right now.

                          Finally, the distinction between null and unset is the difference between explicitly saying "this node is a root node" vs "this node should be added to the default parent" (in some context).

                          Comment


                            #14
                            Originally posted by Isomorphic View Post
                            Just to reiterate: type="Integer" is not a special value. It has the same meaning as type="regetnI".
                            Damn, I sure wanted to be done with this. The fact that I'm taking advantage of unintended behavior is a problem.

                            So when I use "Integer", "regent" or any other random value, I get the following warning:

                            Code:
                            === 2012-07-23 16:48:59,273 [l0-4] WARN  BasicDataSource - Related data source 'domain_DataSource' does not match declared field type  'Integer' for field 'parentDomainId'. Treating as simple field.
                            But if I remove it completely or change it to "int", I get a null pointer exception on the first "root" node insert and then I get a numberformatexception on subsequent inserts/adds. The result is that all of the nodes getting added to the root (with a null domainParentId) even though they were supposed to be added under the root (given a parentId of 1).

                            So I don't know that it means by "treating as a simple field", but that "simple field" treatment makes everything work for me.

                            As far as the NumberFormatException, it sounds like you already have a solution, but we would need actual diagnostic information to help. We don't even know if you mean a client or server exception right now.
                            Here's a snippet of the log file. it includes the log message for the first two operations (initial root insert followed by an insert under the tree). Let me know if or what else you might need.
                            Code:
                            === 2012-07-23 16:51:57,184 [l0-4] DEBUG JPADataSource - Releasing entity manager.
                            === 2012-07-23 16:51:57,252 [l0-4] INFO  RequestContext - URL: '/JPADS_js/sc/IDACall', User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1': Moz (Gecko) with Accept-Encoding header
                            === 2012-07-23 16:51:57,255 [l0-5] DEBUG DSRequest - [builtinApplication.domain_DataSource_fetch] Clobbering existing FreeResourcesHandler of type 'com.isomorphic.jpa.JPADataSource' with a 'com.isomorphic.jpa.JPADataSource'
                            === 2012-07-23 16:51:57,256 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Executing fetch.
                            === 2012-07-23 16:51:57,256 [l0-4] DEBUG XML - Parsed XML from (in memory stream): 3ms
                            === 2012-07-23 16:51:57,256 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Query string: select _Domain from Domain _Domain where _Domain.parentDomainId is null
                            === 2012-07-23 16:51:57,257 [l0-4] DEBUG RPCManager - Processing 1 requests.
                            === 2012-07-23 16:51:57,258 [l0-4] DEBUG RPCManager - Request #1 (DSRequest) payload: {
                                values:{
                                    name:"Global",
                                    parentDomainId:null
                                },
                                operationConfig:{
                                    dataSource:"domain_DataSource",
                                    operationType:"add"
                                },
                                componentId:"isc_TreeGrid_0",
                                appID:"builtinApplication",
                                operation:"domain_DataSource_add",
                                oldValues:{
                                    name:"Global",
                                    parentDomainId:null
                                },
                                criteria:{
                                }
                            }
                            === 2012-07-23 16:51:57,258 [l0-4] INFO  IDACall - Performing 1 operation(s)
                            === 2012-07-23 16:51:57,259 [l0-4] DEBUG AppBase - [builtinApplication.domain_DataSource_add] No userTypes defined, allowing anyone access to all operations for this application
                            === 2012-07-23 16:51:57,259 [l0-4] DEBUG AppBase - [builtinApplication.domain_DataSource_add] No public zero-argument method named '_domain_DataSource_add' found, performing generic datasource operation
                            === 2012-07-23 16:51:57,259 [l0-4] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Auto-joining transactions.
                            === 2012-07-23 16:51:57,262 [l0-4] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Creating EntityManager, starting transaction and setting it to RPCManager.
                            === 2012-07-23 16:51:57,268 [l0-4] DEBUG DSRequest - [builtinApplication.domain_DataSource_add] Clobbering existing FreeResourcesHandler of type 'com.isomorphic.jpa.JPADataSource' with a 'com.isomorphic.jpa.JPADataSource'
                            === 2012-07-23 16:51:57,269 [l0-4] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Executing add.
                            Hibernate: 
                                select
                                    domain0_.id as id25_,
                                    domain0_.name as name25_,
                                    domain0_.parentDomain as parentDo3_25_ 
                                from
                                    T_DOMAIN domain0_ 
                                where
                                    domain0_.parentDomain is null
                            Hibernate: 
                                select
                                    domain0_.id as id25_,
                                    domain0_.name as name25_,
                                    domain0_.parentDomain as parentDo3_25_ 
                                from
                                    T_DOMAIN domain0_ 
                                where
                                    domain0_.id=?
                            === 2012-07-23 16:51:57,277 [l0-5] INFO  DSResponse - [builtinApplication.domain_DataSource_fetch] DSResponse: List with 0 items
                            === 2012-07-23 16:51:57,277 [l0-5] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
                            === 2012-07-23 16:51:57,277 [l0-5] DEBUG JPADataSource - Committing current transaction.
                            === 2012-07-23 16:51:57,278 [l0-5] DEBUG RPCManager - non-DMI response, dropExtraFields: true
                            === 2012-07-23 16:51:57,279 [l0-5] DEBUG JPADataSource - Releasing entity manager.
                            Hibernate: 
                                insert 
                                into
                                    T_DOMAIN
                                    (id, name, parentDomain) 
                                values
                                    (null, ?, ?)
                            Hibernate: 
                                call identity()
                            === 2012-07-23 16:51:57,307 [l0-4] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
                            === 2012-07-23 16:51:57,307 [l0-4] DEBUG JPADataSource - Committing transaction for 1 queued operation(s).
                            === 2012-07-23 16:51:57,311 [l0-4] DEBUG RPCManager - non-DMI response, dropExtraFields: true
                            === 2012-07-23 16:51:57,312 [l0-4] WARN  DataSource - Couldn't get value for property 'parentDomainId' for datasource 'domain_DataSource' - ignoring. Actual error: java.lang.NullPointerException
                            === 2012-07-23 16:51:57,313 [l0-4] DEBUG JPADataSource - Releasing entity manager.
                            === 2012-07-23 16:52:29,623 [l0-5] INFO  RequestContext - URL: '/JPADS_js/sc/IDACall', User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1': Moz (Gecko) with Accept-Encoding header
                            === 2012-07-23 16:52:29,626 [l0-5] DEBUG XML - Parsed XML from (in memory stream): 1ms
                            === 2012-07-23 16:52:29,629 [l0-5] DEBUG RPCManager - Processing 1 requests.
                            === 2012-07-23 16:52:29,630 [l0-5] DEBUG RPCManager - Request #1 (DSRequest) payload: {
                                values:{
                                    name:"new-domain",
                                    parentDomainId:1
                                },
                                operationConfig:{
                                    dataSource:"domain_DataSource",
                                    operationType:"add"
                                },
                                componentId:"isc_TreeGrid_0",
                                appID:"builtinApplication",
                                operation:"domain_DataSource_add",
                                oldValues:{
                                    name:"new-domain",
                                    parentDomainId:1
                                },
                                criteria:{
                                }
                            }
                            === 2012-07-23 16:52:29,630 [l0-5] INFO  IDACall - Performing 1 operation(s)
                            === 2012-07-23 16:52:29,630 [l0-5] DEBUG AppBase - [builtinApplication.domain_DataSource_add] No userTypes defined, allowing anyone access to all operations for this application
                            === 2012-07-23 16:52:29,630 [l0-5] DEBUG AppBase - [builtinApplication.domain_DataSource_add] No public zero-argument method named '_domain_DataSource_add' found, performing generic datasource operation
                            === 2012-07-23 16:52:29,631 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Auto-joining transactions.
                            === 2012-07-23 16:52:29,631 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Creating EntityManager, starting transaction and setting it to RPCManager.
                            === 2012-07-23 16:52:29,632 [l0-5] DEBUG DSRequest - [builtinApplication.domain_DataSource_add] Clobbering existing FreeResourcesHandler of type 'com.isomorphic.jpa.JPADataSource' with a 'com.isomorphic.jpa.JPADataSource'
                            === 2012-07-23 16:52:29,632 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_add] Executing add.
                            Hibernate: 
                                select
                                    domain0_.id as id25_,
                                    domain0_.name as name25_,
                                    domain0_.parentDomain as parentDo3_25_ 
                                from
                                    T_DOMAIN domain0_ 
                                where
                                    domain0_.id=?
                            === 2012-07-23 16:52:29,645 [l0-5] WARN  DataSource - [builtinApplication.domain_DataSource_add] Couldn't set property 'parentDomainId' for datasource 'domain_DataSource'. Actual error: java.lang.NumberFormatException
                            Hibernate: 
                                insert 
                                into
                                    T_DOMAIN
                                    (id, name, parentDomain) 
                                values
                                    (null, ?, ?)
                            Hibernate: 
                                call identity()
                            === 2012-07-23 16:52:29,648 [l0-5] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
                            === 2012-07-23 16:52:29,648 [l0-5] DEBUG JPADataSource - Committing transaction for 1 queued operation(s).
                            === 2012-07-23 16:52:29,654 [l0-5] DEBUG RPCManager - non-DMI response, dropExtraFields: true
                            === 2012-07-23 16:52:29,657 [l0-5] WARN  DataSource - Couldn't get value for property 'parentDomainId' for datasource 'domain_DataSource' - ignoring. Actual error: java.lang.NullPointerException
                            === 2012-07-23 16:52:29,658 [l0-5] DEBUG JPADataSource - Releasing entity manager.
                            === 2012-07-23 16:52:29,692 [l0-5] INFO  RequestContext - URL: '/JPADS_js/sc/IDACall', User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1': Moz (Gecko) with Accept-Encoding header
                            === 2012-07-23 16:52:29,697 [l0-5] DEBUG XML - Parsed XML from (in memory stream): 2ms
                            === 2012-07-23 16:52:29,700 [l0-5] DEBUG RPCManager - Processing 1 requests.
                            === 2012-07-23 16:52:29,702 [l0-5] DEBUG RPCManager - Request #1 (DSRequest) payload: {
                                criteria:{
                                    parentDomainId:1
                                },
                                operationConfig:{
                                    dataSource:"domain_DataSource",
                                    operationType:"fetch",
                                    textMatchStyle:"exact"
                                },
                                componentId:"isc_TreeGrid_0",
                                appID:"builtinApplication",
                                operation:"domain_DataSource_fetch",
                                oldValues:{
                                    parentDomainId:1
                                }
                            }
                            === 2012-07-23 16:52:29,702 [l0-5] INFO  IDACall - Performing 1 operation(s)
                            === 2012-07-23 16:52:29,702 [l0-5] DEBUG AppBase - [builtinApplication.domain_DataSource_fetch] No userTypes defined, allowing anyone access to all operations for this application
                            === 2012-07-23 16:52:29,702 [l0-5] DEBUG AppBase - [builtinApplication.domain_DataSource_fetch] No public zero-argument method named '_domain_DataSource_fetch' found, performing generic datasource operation
                            === 2012-07-23 16:52:29,703 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Creating EntityManager and starting transaction.
                            === 2012-07-23 16:52:29,708 [l0-5] DEBUG DSRequest - [builtinApplication.domain_DataSource_fetch] Clobbering existing FreeResourcesHandler of type 'com.isomorphic.jpa.JPADataSource' with a 'com.isomorphic.jpa.JPADataSource'
                            === 2012-07-23 16:52:29,708 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Executing fetch.
                            === 2012-07-23 16:52:29,708 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Query string: select _Domain from Domain _Domain where _Domain.parentDomainId = :p0
                            === 2012-07-23 16:52:29,720 [l0-5] DEBUG JPADataSource - [builtinApplication.domain_DataSource_fetch] Parameter p0: 1
                            Hibernate: 
                                select
                                    domain0_.id as id25_,
                                    domain0_.name as name25_,
                                    domain0_.parentDomain as parentDo3_25_ 
                                from
                                    T_DOMAIN domain0_ 
                                where
                                    domain0_.parentDomain=?
                            === 2012-07-23 16:52:29,726 [l0-5] INFO  DSResponse - [builtinApplication.domain_DataSource_fetch] DSResponse: List with 0 items
                            === 2012-07-23 16:52:29,726 [l0-5] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
                            === 2012-07-23 16:52:29,726 [l0-5] DEBUG JPADataSource - Committing current transaction.
                            === 2012-07-23 16:52:29,728 [l0-5] DEBUG RPCManager - non-DMI response, dropExtraFields: true
                            === 2012-07-23 16:52:29,729 [l0-5] DEBUG JPADataSource - Releasing entity manager.

                            Comment


                              #15
                              "treating as a simple field" means treating as an ordinary type="text" field as previously discussed.

                              In your log, before the NumberFormatException, when we attempt to call getParentDomainId() there is a NullPointerException. That appears to be the root cause so you should see why your getter would crash.

                              Comment

                              Working...
                              X