Announcement

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

    JPA, ManyToMany update

    Hi,

    I'm using SmartGWTPower 3.1p.

    I got fetching a ManyToMany field to work using the JPADatasource. However I can't seem to get update working.

    Here is the Request shown in the logs:

    Code:
    15:19:44,756 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,756 [43-5] DEBUG RPCManager - Request #1 (DSRequest) payload: {
    15:19:44,756 INFO  [stdout] (http--0.0.0.0-8443-5)     criteria:{
    15:19:44,756 INFO  [stdout] (http--0.0.0.0-8443-5)         id:9
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)     },
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)     values:{
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)         id:9,
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)         roleName:"r1",
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)         actions:[
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)             {
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)                 id:6,
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)                 description:null,
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)                 name:"BASE_ADMIN_USER",
    15:19:44,757 INFO  [stdout] (http--0.0.0.0-8443-5)                 _selection_7:true
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)             },
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)             {
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)                 id:3,
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)                 description:null,
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)                 name:"BASE_ADMIN_GROUP"
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)             }
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)         ],
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)         _selection_11:true
    15:19:44,758 INFO  [stdout] (http--0.0.0.0-8443-5)     },
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     operationConfig:{
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)         dataSource:"roleDs",
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)         operationType:"update"
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     },
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     componentId:"isc_DynamicForm_53",
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     appID:"builtinApplication",
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     operation:"roleDs_update",
    15:19:44,759 INFO  [stdout] (http--0.0.0.0-8443-5)     oldValues:{
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)         id:9,
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)         roleName:"r1",
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)         actions:[
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)             {
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)                 id:3,
    15:19:44,760 INFO  [stdout] (http--0.0.0.0-8443-5)                 description:null,
    15:19:44,761 INFO  [stdout] (http--0.0.0.0-8443-5)                 name:"BASE_ADMIN_GROUP"
    15:19:44,761 INFO  [stdout] (http--0.0.0.0-8443-5)             }
    15:19:44,761 INFO  [stdout] (http--0.0.0.0-8443-5)         ],
    15:19:44,761 INFO  [stdout] (http--0.0.0.0-8443-5)         _selection_11:true
    15:19:44,761 INFO  [stdout] (http--0.0.0.0-8443-5)     }
    15:19:44,762 INFO  [stdout] (http--0.0.0.0-8443-5) }
    15:19:44,762 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,762 [43-5] INFO  IDACall - Performing 1 operation(s)
    It seems to me the request part is in order. (I am adding action id 6 to the ManyToMany field called "actions") I don't see any errors down the log but my suspicion is this line might be the problem:

    Code:
    04-22 15:19:44,777 [43-5] DEBUG JPA2DSGenerator - Plural field skipped: {name=actions, type=any}
    Here is the xml and js output for roleDs:

    Code:
    <DataSource ID="roleDs" serverType="jpa"
    	beanClassName="com.nessotech.base.acl.jpa.Role" schemaBean="com.nessotech.base.acl.jpa.Role"
    	>
    	<field name="actions"
    				hidden="true"
                   canSave="true"
                   canEdit="true"
                   detail="true"
                   type="actionDs"
                   javaCollectionClass="com.nessotech.base.acl.jpa.Action"
                   multiple="true"
                   foreignKey="actionDs.id"/>
    </DataSource>
    Code:
    isc.DataSource.create({
        allowAdvancedCriteria:true,
        idClassName:null,
        inheritsFrom:isc.DataSource.create({
            allowAdvancedCriteria:true,
            dropExtraFields:true,
            ID:"roleDs_inheritsFrom",
            serverType:"jpa",
            generatedBy:"v8.3p_2012-12-11/PowerEdition Deployment 2012-12-11",
            fields:[
                {
                    name:"roleName",
                    length:255,
                    type:"text",
                    required:true,
                    canEdit:true
                },
                {
                    hidden:true,
                    name:"id",
                    primaryKey:true,
                    type:"sequence",
                    canEdit:false,
                    required:false
                }
            ]
        })
    ,
        serverType:"jpa",
        field:{
            canEdit:"true",
            canSave:"true",
            detail:"true",
            foreignKey:"actionDs.id",
            hidden:"true",
            javaCollectionClass:"com.nessotech.base.acl.jpa.Action",
            multiple:"true",
            name:"actions",
            type:"actionDs"
        },
        ID:"roleDs",
        fields:[
        ]
    })
    Here is the xml and js output for actionDs:

    Code:
    <DataSource ID="actionDs" serverType="jpa"
    	beanClassName="com.nessotech.base.acl.jpa.Action" schemaBean="com.nessotech.base.acl.jpa.Action">
    </DataSource>
    Code:
    isc.DataSource.create({
        allowAdvancedCriteria:true,
        idClassName:null,
        ID:"actionDs",
        inheritsFrom:isc.DataSource.create({
            allowAdvancedCriteria:true,
            dropExtraFields:true,
            ID:"actionDs_inheritsFrom",
            serverType:"jpa",
            generatedBy:"v8.3p_2012-12-11/PowerEdition Deployment 2012-12-11",
            fields:[
                {
                    hidden:true,
                    name:"id",
                    primaryKey:true,
                    type:"sequence",
                    canEdit:false,
                    required:false
                },
                {
                    name:"description",
                    type:"text",
                    required:false
                },
                {
                    name:"name",
                    length:255,
                    type:"text",
                    required:true,
                    canEdit:true
                }
            ]
        })
    ,
        fields:[
        ],
        serverType:"jpa"
    })

    Any hints on where I went wrong? Do I have to have an explicit reverse mapping in actionDs?

    Here is the rest of the logs after the request above for completeness:

    Code:
    15:19:44,762 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,762 [43-5] DEBUG DeclarativeSecurity - Processing security checks for DataSource null, field null
    15:19:44,763 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,763 [43-5] DEBUG DeclarativeSecurity - DataSource roleDs is not in the pre-checked list, processing...
    15:19:44,763 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,763 [43-5] DEBUG AppBase - [builtinApplication.roleDs_update] No userTypes defined, allowing anyone access to all operations for this application
    15:19:44,764 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,764 [43-5] DEBUG AppBase - [builtinApplication.roleDs_update] No public zero-argument method named '_roleDs_update' found, performing generic datasource operation
    15:19:44,766 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,766 [43-5] DEBUG JPADataSource - [builtinApplication.roleDs_update] Auto-joining transactions.
    15:19:44,767 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,767 [43-5] DEBUG JPADataSource - [builtinApplication.roleDs_update] Creating EntityManager, starting transaction and setting it to RPCManager.
    15:19:44,769 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,769 [43-5] DEBUG DSRequest - [builtinApplication.roleDs_update] Clobbering existing FreeResourcesHandler of type 'com.isomorphic.jpa.JPA2DataSource' with a 'com.isomorphic.jpa.JPA2DataSource'
    15:19:44,771 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,771 [43-5] DEBUG JPADataSource - [builtinApplication.roleDs_update] Executing update.
    15:19:44,774 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,774 [43-5] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
    15:19:44,774 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,774 [43-5] DEBUG JPADataSource - Committing transaction for 1 queued operation(s).
    15:19:44,775 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,775 [43-5] DEBUG JPA2DSGenerator - Instantiating class com.nessotech.base.acl.jpa.Role
    15:19:44,775 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,775 [43-5] DEBUG JPA2DSGenerator - Generating data source 'Role_JPA' for class com.nessotech.base.acl.jpa.Role
    15:19:44,775 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,775 [43-5] DEBUG JPA2DSGenerator - Generating field 'roleName' of type java.lang.String
    15:19:44,776 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,776 [43-5] DEBUG JPA2DSGenerator - Singular field configuration generated: {extScale=0, extIsUnique=true, name=roleName, length=255, extPrecision=0, canEdit=true, required=true, type=text}
    15:19:44,777 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,777 [43-5] DEBUG JPA2DSGenerator - Generating field 'actions' of type java.util.Set
    15:19:44,777 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,777 [43-5] DEBUG JPA2DSGenerator - Plural field skipped: {name=actions, type=any}
    15:19:44,777 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,777 [43-5] DEBUG JPA2DSGenerator - Generating field 'id' of type java.lang.Short
    15:19:44,778 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,778 [43-5] DEBUG JPA2DSGenerator - Singular field configuration generated: {hidden=true, primaryKey=true, name=id, required=false, canEdit=false, type=sequence}
    15:19:44,778 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,778 [43-5] DEBUG RPCManager - non-DMI response, dropExtraFields: false
    15:19:44,780 INFO  [stdout] (http--0.0.0.0-8443-5) === 2013-04-22 15:19:44,780 [43-5] DEBUG JPADataSource - Releasing entity manager.
    Thanks,

    Ech

    #2
    Hi,

    Your suspicion is not correct: JPA DS generator does not generate relation fields for autoderived data sources.
    Therefore you have to define it manualy. And you did it correctly (at least at first glance).

    Can you post sources for JPA entities?

    Alius

    Comment


      #3
      Hi Alius,

      Here's the code for the Role and Action entities:

      Code:
      package com.nessotech.base.acl.jpa;
      
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;
      import javax.persistence.NamedQueries;
      import javax.persistence.NamedQuery;
      
      @Entity
      @NamedQueries(value={
      		@NamedQuery(name="actionCheck", query="select a from Action a where a.name in :names")
      })
      public class Action {
      
      	Short id;
      	
      	String name;
      	
      	String description;
      
      	
      	
      	public Action(String name) {
      		setName(name);
      	}
      	
      	public Action() {
      	}
      	
      	@Id
      	@GeneratedValue(strategy=GenerationType.SEQUENCE)
      	public Short getId() {
      		return id;
      	}
      
      	public void setId(Short id) {
      		this.id = id;
      	}
      
      	@Column(nullable=false, unique=true, updatable=false)
      	public String getName() {
      		return name;
      	}
      
      	public void setName(String name) {
      		this.name = name;
      	}
      
      	public String getDescription() {
      		return description;
      	}
      
      	public void setDescription(String description) {
      		this.description = description;
      	}
      		
      }
      Code:
      package com.nessotech.base.acl.jpa;
      
      import java.util.Set;
      
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.FetchType;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;
      import javax.persistence.JoinColumn;
      import javax.persistence.JoinTable;
      import javax.persistence.ManyToMany;
      import javax.persistence.NamedQueries;
      import javax.persistence.NamedQuery;
      
      /**
       * 
       * Custom Permission sets
       *
       */
      @Entity
      @NamedQueries(value={
      		@NamedQuery(name="getSuperUser", query="select r from Role r where r.roleName = 'superuser' ")
      })
      public class Role {
      
      	private Short id; 
      	
      	private String roleName;
      	
      	private Set<Action> actions;
      	
      	@Id
      	@GeneratedValue(strategy=GenerationType.SEQUENCE)
      	public Short getId() {
      		return id;
      	}
      
      	public void setId(Short id) {
      		this.id = id;
      	}
      
      	@Column(nullable=false,unique=true)
      	public String getRoleName() {
      		return roleName;
      	}
      
      	public void setRoleName(String roleName) {
      		this.roleName = roleName;
      	}
      
      	@ManyToMany(fetch=FetchType.EAGER)
      	public Set<Action> getActions() {
      		return actions;
      	}
      
      	public void setActions(Set<Action> actions) {
      		this.actions = actions;
      	}
      	
      }
      As stated previously, the fetch operations seem to be working fine. That's what confuses me about the updates not working.

      Thanks,

      Ech

      Comment


        #4
        Hi,

        Your DS definition is incorrect: you have missed <fields> tag. Should be:
        Code:
        <DataSource ID="roleDs" serverType="jpa"
        	beanClassName="com.nessotech.base.acl.jpa.Role" schemaBean="com.nessotech.base.acl.jpa.Role"
        	>
        <fields> <!-- this line was missing in initial DS definition -->
        	<field name="actions"
        				hidden="true"
                       canSave="true"
                       canEdit="true"
                       detail="true"
                       type="actionDs"
                       javaCollectionClass="com.nessotech.base.acl.jpa.Action"
                       multiple="true"
                       foreignKey="actionDs.id"/>
        </fields> <!-- this line was missing in initial DS definition -->
        </DataSource>
        Regards,
        Alius

        Comment


          #5
          That worked. Thanks!

          Just a small follow up so I won't have to repost the same code and logs in another thread:

          The selected records were being posted with extra fields in the request. The field seems to be a generated one with the format "_selection_#". This can be seen in the logs provided before:

          Code:
          _selection_7:true
          The records still get updated anyway with the logs saying something like:

          Code:
          09:51:37,286 INFO  [stdout] (http--0.0.0.0-8443-11) === 2013-04-30 09:51:37,286 [3-11] INFO  DataTools - [builtinApplication.roleDs_update] setProperties: couldn't set:
          09:51:37,287 INFO  [stdout] (http--0.0.0.0-8443-11) {
          09:51:37,287 INFO  [stdout] (http--0.0.0.0-8443-11)     _selection_6:"No such property"
          09:51:37,287 INFO  [stdout] (http--0.0.0.0-8443-11) }
          I was just curious if this is an expected behavior or maybe I set something somewhere to cause this.

          Thanks,

          Ech

          Comment

          Working...
          X