JavaAction does not Return New Uncommited Object

0
Use Case: We have an Entity that is Passed into a Java Action. Inside the Action we clone this Object, some Magic happens, and some Attributes will be Changed on the new Object using the SetValue Java (IMendixObject)Method. After we return the New Object to the “MX Context” the changes are Lost, the Members are still having the Values of the Original Object PseudoCode (executeAction): → JAVA CONTEXT MyType  newObject = MyType .initialize(userContext, originalObject.getMendixObject()); IMendixObject newMendixObject = newObject.getMendixObject(); log(newMendixObject.getValue(“attrName”);   // Will Print oldValu newMendixObject .setValue(userContext, “attrName”, “newValue”); // Apply the Changes log(newMendixObject.getValue(“attrName”);   // Will Print newValue return newMendixObject; → MX Context The Returned Object still has the values of the Original Object and not the newValue
asked
3 answers
0
  1. Sample Domain Model
  2. Sample Code:
    // This file was generated by Mendix Studio Pro.
    //
    // WARNING: Only the following code will be retained when actions are regenerated:
    // - the import list
    // - the code between BEGIN USER CODE and END USER CODE
    // - the code between BEGIN EXTRA CODE and END EXTRA CODE
    // Other code you write will be lost the next time you deploy the project.
    // Special characters, e.g., é, ö, à, etc. are supported in comments.
    
    package logs.actions;
    
    import java.util.List;
    import com.mendix.core.Core;
    import com.mendix.core.CoreException;
    import com.mendix.systemwideinterfaces.core.IContext; 
    import com.mendix.webui.CustomJavaAction;
    import audittrail.proxies.Log;
    import audittrail.proxies.LogLine;
    import logs.proxies.Version;
    import logs.proxies.Versionable;
    import threatriskanalysis.proxies.ThreatRiskAnalysisAll;
    import com.mendix.systemwideinterfaces.core.IMendixObject;
    import com.mendix.systemwideinterfaces.core.IContext;
    import com.mendix.logging.ILogNode;
    
    public class RebuildVersion extends CustomJavaAction<IMendixObject>
    {
    	private IMendixObject __Parameter;
    	private logs.proxies.Version Parameter;
    
    	public RebuildVersion(IContext context, IMendixObject Parameter)
    	{
    		super(context);
    		this.__Parameter = Parameter;
    	}
    
    	@java.lang.Override
    	public IMendixObject executeAction() throws Exception
    	{
    		this.Parameter = __Parameter == null ? null : logs.proxies.Version.initialize(getContext(), __Parameter);
    
    		// BEGIN USER CODE
    		Version version = Version.initialize(getContext(), __Parameter);
    		
    		// Jump from the Version to the Versionable
    		Versionable versionable = version.getVersion_Versionable();
    		
    		IContext userContext = getContext();
    		
    		//Create a Copy of the Versionable Object
    		IMendixObject versionableNew = Versionable.initialize(userContext, versionable.getMendixObject()).getMendixObject();
    		
    		//Change something in the copy
    		versionableNew.setValue(userContext, "SampleField", "New Value");
    		return versionableNew;
    	
    		// END USER CODE
    	}
    
    	/**
    	 * Returns a string representation of this action
    	 */
    	@java.lang.Override
    	public java.lang.String toString()
    	{
    		return "RebuildVersion";
    	}
    
    	// BEGIN EXTRA CODE
    	
    	// END EXTRA CODE
    }
    

     

  3. Result Remains Empty:

 

 

 

 

 

answered
0

As Ilya has said in the comments, it looks like you have used initialize to try to clone the object, but all this is doing is making the passed object available as a proxy object for you.

You need to look at using Core.instantiate to create a new object, or just use the proxy classes generated by Mendix.

If you want to see how to clone an object in Java, have a look in the Community Commons module, there are a few methods there that will show you how to do this. For example...

https://github.com/mendix/CommunityCommons/blob/master/src/CommunityCommons/javasource/communitycommons/ORM.java#L69

You may find the functionality provided in Community Commons to clone objects does what you need already, so you may not have to write your own action, and you can just change values in the clone from a microflow instead.

Hope this helps.

answered
0

Use the constrcutor in your proxy class directly and leave the rest of the implementation details to Mendix itself.     

Version newVersion = new Version(getContext());

I dont understand why we must bother about using Core methods. But for the sake of understanding: 

Constructor (using instantiate)

this(context, com.mendix.core.Core.instantiate(context, "Administration.Account"));

Clone method

As Robert suggested, you can also use Clone or DeepClone from community commons. But you must create the new object from the microflow and pass it on to the java action, which set the data members to the values of source.

NOTE: if you want new objects for associations then you must create new ones.

Suggestion

Create object from microflow and use clone or deepclone. Or if business demands creating objects from java, then use the constrcutor.

Also I see that you are using IMendixObject for setting values. You could use setter methods from proxy once again.

answered