Search code examples
mysqlgoogle-cloud-datastorejdodatanucleus

JDO tries to create a new record when associating using one to many relation


I am using datanucleus/MySQL5.6/Google App Engine1.9.4/JDO3.0/Spring3.0.

Situation is, I have a User class

@PersistenceCapable(table="Users")
public class User {
    @PrimaryKey
    @Persistent(column="UserID", valueStrategy=IdGeneratorStrategy.NATIVE)
    private Long ID;
    //some more fields below
}

I have a UserSession class

@PersistenceCapable(table="usersessions")
public class UserSession extends DomainObject {

    private static final long serialVersionUID = 1L;

    @PrimaryKey
    @Persistent(column="SessionID", valueStrategy=IdGeneratorStrategy.NATIVE)
    private Long ID;

    @Persistent
    @Column(name="UserID")
    private User user;

}

I have one to many relation between User to UserSession. In UserSession table i have defined a foreign key refering to userid(primary key) of User table.

I have created User record when user first time registers.

Everytime user logs in I create a UserSession record in the database. I am able to create User record successfully in DB. When user logs in i am creating a UserSession object, associating the previously retrieved User object to UserSession object.

When i persist UserSession, it is trying to create a new User record in the database.

I only want to associate existing User record with a newly created UserSession object.

I do not want to have bidirectional one-to-many association.

Below is the code for creating UserSession object,

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UserSession createSession(User user, String sessionId) {
        PersistenceManager pm = persistenceManagerFactory.getPersistenceManager();
        try {
            UserSession userSession = new UserSession();
            userSession.setAppSession(sessionId);
            userSession.setUser(user);
            pm.makePersistent(user);
            return userSession;
        } finally {
            pm.close();
        }
    }

Please Help. Thanks in advance.


Solution

  • if the object is in transient state then it will create a NEW object, just like the JDO specification says. And the log would tell you what state it is in, so no need to guess.

    If you don't want a NEW object you pass a managed (persistent-clean, hollow, etc) or detached object in when you call makePersistent.