aronp
aronp

Reputation: 799

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

Upvotes: 1

Views: 938

Answers (2)

Blackhex
Blackhex

Reputation: 1754

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);

Upvotes: 0

DataNucleus
DataNucleus

Reputation: 15577

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

Upvotes: 2

Related Questions