0

I have two entities: Account, Home. The relationship is such

@Entity
public class Account implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key userId;
    private String data;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Home> homes = new ArrayList<Home>();

    public Account() {
    }

    public Account(String data) {
        this. data = data;
    }

    public Account(String data, List<Home> homes) {
        super();
        this. data = data;
        this.homes = homes;
    }

    public List<Home> getHomes() {
        return homes;
    }

    public void setHomes(List<Home> homes) {
        this.homes = homes;
    }

}

//HOME

@Entity
public class Home implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
    private long timestamp;
    private long userId;

    public Home(long latlong, long userId) {
        Key key = KeyFactory.createKey(Home.class.getSimpleName(), latlong + "" + userId);
        this.key = key;
        this.userId = userId;
    }

    //getters and setters
}

The invariants are such that the latlong for a user never changes. Therefore, when I add a Home entity, if one already exists for said user, it is simply replaced in the datastore. So far so good. But I am getting a problem for the following user case:

Say user X edit his home data 6 times. Sure enough when I look in the datastore, there is only one entry for Home and it contains the latest data. But after querying for Account using datanucleus, when I do getHomes().size() the result is 6. Apparently datanucleus is caching every single edit as an individual entity. It’s a mystery to me. I am logging the code so I am seeing it happening: For the exact same key (I use a for-loop), I am getting each iteration/edit of the entity. How do I keep this from happening? The datastore clearly shows one entity for the key. I just want that one entity: no historical list.

My datanucleus/jpa getById is

@Override
    public T getById(Long id) {
        EntityManager mgr = getEntityManager();
        try {
            return null == id ? null : mgr.find(type, id);
        } finally {
            mgr.close();
        }
    }
Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
learner
  • 11,490
  • 26
  • 97
  • 169
  • Would have thought that if you are baffled then looking at the log for datastore accesses (all logged IIRC), and wrapping of collection fields with wrappers (also IIRC). That way you can base things on more than what "seems" to be happening IMO – Neil Stockton Jun 01 '14 at 17:41

1 Answers1

0

Still baffled per the root cause of the problem, I replaced List with Set and my problem is now solved.

learner
  • 11,490
  • 26
  • 97
  • 169