ConfirmBehavior dosen't support Ajax rendreing - primefaces

After an Ajax update of a button with a ConfirmBehavior, all Confirm dialog attributes (Header, Message, Icon) becomes Null.
Its look like thoses values are evaluated during the buildView phase only (applyMetadata function)
In the getHeader()/getMessage()/getIcon() methods of the ConfirmBehavior there is no evaluation of expression.
How to get the real expression at this point ? (to evaluate it during the render phase)

Not a perfect solution
public class ConfirmBehavior extends ClientBehaviorBase {
private String header;
private String message;
private String icon;
#Override
public String getScript(ClientBehaviorContext behaviorContext) {
FacesContext context = behaviorContext.getFacesContext();
UIComponent component = behaviorContext.getComponent();
String source = component.getClientId(context);
if(component instanceof Confirmable) {
String headerExpr = (String) component.getAttributes().get("confirm_header");
if (headerExpr!=null)
this.header = (String) ContextUtil.eval(context, headerExpr);
String messageExpr = (String) component.getAttributes().get("confirm_message");
if (messageExpr!=null)
this.message = (String) ContextUtil.eval(context, messageExpr);
String iconExpr = (String) component.getAttributes().get("confirm_icon");
if (iconExpr!=null)
this.icon = (String) ContextUtil.eval(context, iconExpr);
String script = "PrimeFaces.confirm({source:'" + source + "',header:'" + getHeader() + "',message:'" + getMessage() + "',icon:'" + getIcon() + "'});return false;";
((Confirmable) component).setConfirmationScript(script);
return null;
}
else {
throw new FacesException("Component " + source + " is not a Confirmable. ConfirmBehavior can only be attached to components that implement org.primefaces.component.api.Confirmable interface");
}
}
...
}

Related

mock.method call returns null after stubbing

I am trying to test using Mockito
my class under test is
#Service
public class DynatraceAPIServiceImpl implements DynatraceAPIService {
private String apiUrl = "someurl";
private String apiToken = "sometoken";
#Override
public CreateCustomMetricResponse createCustomMetric(CreateCustomMetricRequest request) throws MonitoringException {
logger.info("Inside create custom metric");
if (request == null) {
logger.error("create metric request is null");
throw new MonitoringException("Create metric request is null");
}
String metricId = DynatraceConstants.METRIC_ID;
String displayName = request.getDisplayName();
CreateCustomMetricResponse response = httpUtils.postCustomMetric(apiUrl + "/v1/timeseries/" + metricId, apiToken, request);
if (response == null) {
logger.error("Error in creating custom metric with name : " + displayName);
throw new MonitoringException("Error in creating custom metric with name : " + displayName);
}
logger.info("Custom metric : " + displayName + " is created successfully.");
return response;
}
}
and my Test class is :
#RunWith(MockitoJUnitRunner.class)
public class DynatraceAPIServiceImplTest {
#InjectMocks
DynatraceAPIServiceImpl dynatraceAPIServiceImpl;
#Mock
DynatraceHttpUtils httpUtilsMock;
#Mock
DynatraceMonitoringUtils monitoringUtilsMock;
#Test(expected = MonitoringException.class)
public void createCustomMetricGetsNonNullResponse() throws MonitoringException {
CreateCustomMetricRequest mockRequest = CreateCustomMetricRequest.builder()
.displayName(DISPLAY_NAME)
.types(new String[] {"test-type"})
.build();
CreateCustomMetricResponse response = CreateCustomMetricResponse.builder()
.displayName(DISPLAY_NAME)
.types(new String[] {"test-type"})
.timeseriesId(TIMESERIES_ID)
.build();
boolean val = true;
when(monitoringUtilsMock.isValidMetricIdValue(anyString())).thenReturn(val);
when(httpUtilsMock.postCustomMetric(API_URL + "/v1/timeseries/" + METRIC_ID, API_TOKEN, mockRequest)).thenReturn(response);
CreateCustomMetricResponse actualRespnose = dynatraceAPIServiceImpl.createCustomMetric(mockRequest);
//verify(httpUtilsMock, times(1)).postCustomMetric(anyString(), anyString(), any(CreateCustomMetricRequest.class));
//assertEquals(actualRespnose.getDisplayName(), DISPLAY_NAME);
}
}
Here, when I execute the tests, it always end up having the response value to be null in line
CreateCustomMetricResponse response = httpUtils.postCustomMetric(apiUrl + "/v1/timeseries/" + metricId, apiToken, request);
Even if I have used when() statement to return response as I have created, it is returning null.
Really appreciate if someone can let me know what is wrong here. Thanks.
That normally happens when the params your production code uses differ from the ones that you stubbed the call with, an easy way to find out is to write the test like this
when(httpUtilsMock.postCustomMetric(any(), any(), any())).thenReturn(response);
CreateCustomMetricResponse actualRespnose = dynatraceAPIServiceImpl.createCustomMetric(mockRequest);
verify(httpUtilsMock).postCustomMetric(API_URL + "/v1/timeseries/" + METRIC_ID, API_TOKEN, mockRequest);
If you do that, you'll get a nicer error showing the difference between what your code did and what you verified it for
A better approach in general is to use 'strict stubs' so if your code does anything different to what you stubbed the mock for you'll get a nice error telling you what, where and why

_class property in CouchBase

I have a document stored in Couchbase.
{
"a": {
"b": {
"key":"Value"
},
"_class":"com.nikhil.model"
},
"c":{
"d":{
"key":"value"
},
// _class is missing here
},
"_class": "com.nikhil.model"
}
Here as you can see I don't have an _class inside the "d" in the doucument because of this I am not able to get this document. An object mapping exception came.
_class is used to map the nested object of couchbase to the model required for mapping but inside the "c" object I don't have this _Class property that is why a mapping exception comes.
Is there any fix for this?
If you are using Spring boot, you need to override the typekey() method in the Couchbase Config file which extends AbstractCouchbaseConfiguration and return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE. This will replace your _class with javaClass string in the documents stored in Couchbase Server. I hope this helps.
#Configuration
public class RemoteCouchbaseConfiguration extends AbstractCouchbaseConfiguration {
#Value("${couchbase.host}")
private String host;
#Value("${couchbase.bucket.bucketName}")
private String bucketName;
#Value("${couchbase.bucket.password}")
private String password;
#Override
protected List<String> getBootstrapHosts() {
return Arrays.asList(this.host);
}
#Override
protected String getBucketName() {
return this.bucketName;
}
#Override
protected String getBucketPassword() {
return this.password;
}
#Override
public String typeKey() {
return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE;
}
}
Looks like you are using Couchbase with Spring Data, the easiest way is to return a projection:
#Override
public List<UserVO> getUsers(String companyId, List<String> userIds) {
String queryString = "SELECT meta(t).id as id, t.login as login, t.firstName as firstName from " + getBucketName() + " t where t."+getClassFilter()+" "
+ " and t.companyId = '" + companyId + "' and t.isEnabled = true and t.isVisible = true "
+ " and meta(t).id in ["+userIds.stream().map(e->"'"+e+"'").collect( Collectors.joining( "," )) +"]";
N1qlParams params = N1qlParams.build().consistency(ScanConsistency.NOT_BOUNDED).adhoc(true);
ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);
return userRepository.getCouchbaseOperations().findByN1QLProjection(query, UserVO.class);
}
You could add _class to it using an UPDATE N1QL statement like this:
UPDATE mybucket b
SET b.c.d._class = 'com.foo.bar'
WHERE b.c.d IS NOT MISSING
AND b.c.d._class IS MISSING
That will update any document that has a 'd' object within a 'c' object but doesn't have a '_class' within the c object.

gson flat json to nested objects needs serializer/deserializer?

I have some JSON coming in (I don't have any control or ability to change the structure and/or naming within the JSON...important to keep in mind in this question) that has a "flat" structure similar to this:
{
"name": "...",
"email": "...",
"box_background_color": "...",
"box_border_color": "...",
"box_text_color": "...",
...
}
Now, I can just create a simple object that keeps everything flat, like so:
public class Settings {
#SerializedName("name")
private String _name;
#SerializedName("email")
private String _emailAddress;
#SerializedName("box_background_color")
private String _boxBackgroundColor;
#SerializedName("box_border_color")
private String _boxBorderColor;
#SerializedName("box_text_color")
private String _boxTextColor;
...
}
However, I want everything associated with box settings to be in it's own class (BoxSettings). This is more like what I want:
public class Settings {
#SerializedName("name")
private String _name;
#SerializedName("email")
private String _emailAddress;
private BoxSettings _boxSettings
...
}
public class BoxSettings {
#SerializedName("box_background_color")
private String _boxBackgroundColor;
#SerializedName("box_border_color")
private String _boxBorderColor;
#SerializedName("box_text_color")
private String _boxTextColor;
...
}
I know that if the JSON was structured such that the box settings were nested then it would be easy to accomplish what I want, however, I don't have the ability to change the structure of the JSON, so please don't suggest that (I would do it if I could).
My question is this: Is creating an entire TypeAdapter the only way to accomplish what I want or can I still accomplish most of this with annotations? If it is not the only way, how else can I accomplish this without changing the JSON at all?
The following is an example of what I mean by "creating an entire TypeAdapter":
public class SettingsTypeAdapter implements JsonDeserializer<Settings>, JsonSerializer<Settings> {
#Override
public JsonElement serialize(Settings src, Type typeOfSrc, JsonSerializationContext context) {
// Add _name
// Add _emailAddress
// Add BoxSettings._boxBackgroundColor
// Add BoxSettings._boxBorderColor
// Add BoxSettings._boxTextColor
return jsonElement;
}
#Override
public Settings deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// Read _name
// Read _emailAddress
// Read BoxSettings._boxBackgroundColor
// Read BoxSettings._boxBorderColor
// Read BoxSettings._boxTextColor
return settings;
}
}
The TypeAdapter is not the only way, but in this case would be the best way since you can associate the adapter with a Gson instance (or whatever library you are using) and have all your mapping code there.
Another way is to use JAVA reflection. I've used a version of the below code in my projects before but never with JSON and never with nested objects (mostly when there was no other choice or if i wanted to map a SQL result set to a Java object without calling resultSet.get... a lot of times).
This will work in this case.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.json.JSONObject;
public class Main {
public static void main(String[] args) {
try {
String json = "{\"name\": \"test name\", \"email\": \"email#email.com\", \"box_background_color\": \"red\", \"box_border_color\": \"orange\", \"box_text_color\": \"white\", \"test3_var2\":3}";
JSONObject jsonObject = new JSONObject(json);
System.out.println(jsonObject);
System.out.println();
/*
* need to parse JSON into a map of String, Object
*/
Map<String, Object> mapAll = new HashMap<String, Object>();
Iterator<String> iter = jsonObject.keys();
while (iter.hasNext()) {
String key = (String) iter.next();
Object value = jsonObject.get(key);
mapAll.put(key, value);
System.out.println(key + "::::" + value);
}
System.out.println();
/*
* use the mapper to generate the objects
*/
MyMapper<TestClass1> myMapper = new MyMapper<TestClass1>();
TestClass1 result = myMapper.mapToObject(mapAll, TestClass1.class);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyMapper<T> {
#SuppressWarnings("unchecked")
public T mapToObject(Map<String, Object> flatStructure, Class<T> objectClass) {
T result = null;
Field[] fields = null;
try {
// new base object
result = objectClass.newInstance();
// get all of its fields
fields = objectClass.getDeclaredFields();
for (Field field : fields) {
// normal variable
if (field.isAnnotationPresent(MyColumn.class)) {
String variableKey = field.getAnnotation(MyColumn.class).variableKey();
setJavaFieldValue(result, field.getName(), flatStructure.get(variableKey));
}
// variable that is an object and itself has to be mapped
else if (field.isAnnotationPresent(MyInnerColumn.class)) {
String startsWith = field.getAnnotation(MyInnerColumn.class).startsWith();
// reduce the map to only have attributes that are related to this field
Map<String, Object> reducedMap = reduceMap(startsWith, flatStructure);
// make sure that there are attributes for the inner object
if (reducedMap != null) {
// map the inner object
MyMapper<T> myMapper = new MyMapper<T>();
T t2 = myMapper.mapToObject(reducedMap, (Class<T>) field.getType());
// set the mapped object to the base objecct
setJavaFieldValue(result, field.getName(), t2);
}
} else {
// no annotation on the field so ignored
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private Map<String, Object> reduceMap(String startsWith, Map<String, Object> mapToReduce) {
Map<String, Object> result = new HashMap<String, Object>();
for (Map.Entry<String, Object> entry : mapToReduce.entrySet()) {
if (entry.getKey().toLowerCase().startsWith(startsWith.toLowerCase())) {
result.put(entry.getKey(), entry.getValue());
}
}
return result.size() == 0 ? null : result;
}
private void setJavaFieldValue(Object object, String fieldName, Object fieldValue) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
boolean fieldAccess = field.isAccessible();
// make the field accessible
field.setAccessible(true);
field.set(object, fieldValue);
// put it back to the way it was
field.setAccessible(fieldAccess);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
* Annotation for a regular variable / field
*/
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
#interface MyColumn {
// the variable's JSON key
String variableKey() default "";
}
/*
* Annotation for an inner / nested variable / field
*/
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
#interface MyInnerColumn {
/*
* JSON keys that start with this string will be
* associated with this nested field
*/
String startsWith() default "";
}
class TestClass1 {
#MyColumn(variableKey = "name")
private String _name;
#MyColumn(variableKey = "email")
private String _emailAddress;
#MyInnerColumn(startsWith = "box_")
private TestClass2 innerClass;
#MyInnerColumn(startsWith = "test3_")
private TestClass3 innerClass2;
#Override
public String toString() {
return "TestClass1 [_name=" + _name + ", _emailAddress=" + _emailAddress + ", innerClass=" + innerClass + ", innerClass2=" + innerClass2 + "]";
}
}
class TestClass2 {
#MyColumn(variableKey = "box_background_color")
private String _boxBackgroundColor;
#MyColumn(variableKey = "box_border_color")
private String _boxBorderColor;
#MyColumn(variableKey = "box_text_color")
private String _boxTextColor;
#Override
public String toString() {
return "TestClass2 [_boxBackgroundColor=" + _boxBackgroundColor + ", _boxBorderColor=" + _boxBorderColor
+ ", _boxTextColor=" + _boxTextColor + "]";
}
}
class TestClass3 {
#MyColumn(variableKey = "test3_var1")
private String _test3Var1;
#MyColumn(variableKey = "test3_var2")
private int _test3Var2;
#Override
public String toString() {
return "TestClass3 [_test3Var1=" + _test3Var1 + ", _test3Var2=" + _test3Var2 + "]";
}
}
Output
{"box_background_color":"red","box_text_color":"white","test3_var2":3,"name":"test name","email":"email#email.com","box_border_color":"orange"}
box_background_color::::red
box_text_color::::white
test3_var2::::3
name::::test name
email::::email#email.com
box_border_color::::orange
TestClass1 [_name=test name, _emailAddress=email#email.com, innerClass=TestClass2 [_boxBackgroundColor=red, _boxBorderColor=orange, _boxTextColor=white], innerClass2=TestClass3 [_test3Var1=null, _test3Var2=3]]

Grid in Struts2 using struts2-jquery-grid plugin

I'm trying with a Struts jQuery grid using the struts2-jquery-grid-3.7.0 plugin as demonstrated on the showcase, Grid (Editable/Multiselect).
The Struts form:
<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
<s:url id="remoteurl" action="TestGrid" namespace="/admin_side"/>
<s:url id="editurl" action="edit-grid-entry"/>
<sjg:grid
id="gridmultitable"
caption="Example (Editable/Multiselect)"
dataType="json"
href="%{remoteurl}"
pager="true"
navigator="true"
navigatorSearchOptions="{sopt:['eq','ne','lt','gt']}"
navigatorAddOptions="{height:280, width:500, reloadAfterSubmit:true}"
navigatorEditOptions="{height:280, width:500, reloadAfterSubmit:false}"
navigatorEdit="true"
navigatorView="true"
navigatorViewOptions="{height:280, width:500}"
navigatorDelete="true"
navigatorDeleteOptions="{height:280, width:500,reloadAfterSubmit:true}"
gridModel="gridModel"
rowList="5,10,15"
rowNum="5"
rownumbers="true"
editurl="%{editurl}"
editinline="true"
multiselect="true"
onSelectRowTopics="rowselect"
>
<sjg:gridColumn name="countryId" index="countryId" title="Id" formatter="integer" editable="false" sortable="true" search="true" sorttype="integer" searchoptions="{sopt:['eq','ne','lt','gt']}"/>
<sjg:gridColumn name="countryName" index="countryName" title="Country Name" editable="true" edittype="text" sortable="true" search="true" sorttype="text"/>
<sjg:gridColumn name="countryCode" index="countryCode" title="Country Code" sortable="true" search="true" editable="true" sorttype="text"/>
</sjg:grid>
</s:form>
The action class:
#Namespace("/admin_side")
#ResultPath("/WEB-INF/content")
#ParentPackage(value = "json-default")
#InterceptorRefs(#InterceptorRef(value = "store", params = {"operationMode", "AUTOMATIC"}))
public final class TestAction extends ActionSupport implements Serializable
{
#Autowired
private final transient CountryService countryService=null;
private static final long serialVersionUID = 1L;
// Result List
private List<Country> gridModel;
// Get how many rows we want to have into the grid - rowNum attribute in the grid
private Integer rows=5;
// Get the requested page. By default grid sets this to 1.
private Integer page=1;
// sorting order - asc or desc
private String sord;
// get index row - i.e. user click to sort.
private String sidx;
// Search Field
private String searchField;
// The Search String
private String searchString;
// The Search Operation ['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
private String searchOper;
// Your Total Pages
private Integer total;
// All Records
private Integer records;
#Action(value = "TestGrid",
results = {
#Result(name = ActionSupport.SUCCESS, type = "json", params = {"includeProperties", "gridModel\\[\\d+\\]\\.countryId, gridModel\\[\\d+\\]\\.countryName, gridModel\\[\\d+\\]\\.countryCode", "excludeNullProperties", "true"})},
interceptorRefs = {
#InterceptorRef(value = "json")})
public String execute() {
records=countryService.rowCount().intValue();
total=new BigDecimal(records).divide(new BigDecimal(rows), 0, BigDecimal.ROUND_CEILING).intValue();
gridModel=countryService.getList(page, rows, null, null);
System.out.println("records "+records+" total "+total+" Page " + getPage() + " Rows " + getRows() + " Sort Order " + getSord() + " Index Row :" + getSidx()+"Search :" + searchField + " " + searchOper + " " + searchString);
return SUCCESS;
}
public String getJSON() {
return execute();
}
public Integer getRows() {
return rows;
}
public void setRows(Integer rows) {
this.rows = rows;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getRecords() {
return records;
}
public void setRecords(Integer records) {
this.records = records;
}
public List<Country> getGridModel() {
return gridModel;
}
public void setGridModel(List<Country> gridModel) {
this.gridModel = gridModel;
}
public String getSord() {
return sord;
}
public void setSord(String sord) {
this.sord = sord;
}
public String getSidx() {
return sidx;
}
public void setSidx(String sidx) {
this.sidx = sidx;
}
public void setSearchField(String searchField) {
this.searchField = searchField;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public void setSearchOper(String searchOper) {
this.searchOper = searchOper;
}
#Action(value = "Test",
results = {
#Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
#Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
#InterceptorRef(value = "defaultStack", params = {"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public String load() throws Exception {
return ActionSupport.SUCCESS;
}
}
The next and previous pagination links are always disabled as shown in the following snap shot.
It indicates, page 1 of 1. There are no more pages. Hence, the links are disabled.
In the execute() method, however, records is initialized to 31, total to 7 Page to 1 Rows to 5. All other properties are always null whether or not links/buttons for sorting, searching, editing, adding a row are clicked.
What am I overlooking here?
You forgot to include fields to json result that are necessary for grid to function properly. Change to
#Result(type = "json", params = {"includeProperties", "gridModel\\[\\d+\\]\\.countryId, gridModel\\[\\d+\\]\\.countryName, gridModel\\[\\d+\\]\\.countryCode, total, records, rows, page, sord, sidx, searchField, searchString, searchOper", "excludeNullProperties", "true"})
Also, json interceptor is not necessary, but params is required.
#InterceptorRef("params")

Datanucleus JDO setting fields to null

In an attempt to find another issue, my tests came up with the following bit of code.
public class TestPersistance {
private static final PersistenceManagerFactory PMF = JDOHelper.getPersistenceManagerFactory("datanucleus.properties");
public static final PersistenceManager pm = PMF.getPersistenceManager();
static final TestUserDataDB ud = new TestUserDataDB();
public static void main(String args[])
{
TestPersistance tp = new TestPersistance();
tp.createData();
}
#Test public void createData()
{
assertTrue("Null machined id at start", ud.machineId != null);
pm.currentTransaction().begin();
try
{
pm.makePersistent(ud);
}
finally
{
pm.currentTransaction().commit();
}
assertTrue("Null machined id at end", ud.machineId != null);
}
}
where the second assert fails. ie. my object that I am asking to be persisted is being changed by the makePersistent call. The data is being stored in the database.
Any ideas? Can any one confirm this.
using
jdo-api-3.0.jar
datanucleus-core-2.2.0-release.jar
datanucleus-enhancer-2.1.3.jar
datanucleus-rdbms-2.2.0-release.jar
mysql-connector-java-5.1.13.jar
in eclipse with MySql database.
#PersistenceCapable
public class TestUserDataDB {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
public Long id;
#Persistent
public String userid = "test1";
#Persistent
public String machineId = "test2";
// local userid
#Persistent
public long uid = 1L;
#Persistent
public long systemTime = 123L;
public long chk = 1234L;
public long createTime = System.currentTimeMillis();
public TestUserDataDB()
{
}
#Override
public String toString() {
return "TestUserDataDB [chk=" + chk + ", createTime=" + createTime
+ ", id=" + id + ", machineId=" + machineId + ", systemTime="
+ systemTime + ", uid=" + uid + ", userid=" + userid + "]";
}
}
Properties file is
javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.jdo.JDOPersistenceManagerFactory
datanucleus.metadata.validate=false
javax.jdo.option.ConnectionDriverName=com.mysql.jdbc.Driver
javax.jdo.option.ConnectionURL=jdbc:mysql://localhost/test
javax.jdo.option.ConnectionUserName=root
javax.jdo.option.ConnectionPassword=yeahRight
datanucleus.autoCreateSchema=true
datanucleus.validateTables=false
datanucleus.validateConstraints=false
Why are you accessing fields directly ? Is the accessing class declared as PersistenceAware ? Well it isn't so you can't do that - use the getters.
What is "ud" object state before persist ? (transient?) what is it after persist ? (hollow?) What does the log say ? Chances are that it is in hollow state and then you access a field directly and it has no value (by definition, as per the spec) ... but since you didn't bother calling the getter it hasn't a chance to retrieve the value. And you likely also don't have "RetainValues" persistent property set
Suggest you familiarise yourself with the JDO spec and object lifecycle states
In some cases, it is necessary to access deserialized objects' attributes directly (i.e. if using GSON library for JSON serialization). In that case you can use:
MyClass copy = myPersistencyManager.detachCopy(myRetrievedInstance);