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();
}
}
Still baffled per the root cause of the problem, I replaced
List
withSet
and my problem is now solved.