JPA Datanucleus showing old data that is no longer in datastore

70 Views Asked by At

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();
        }
    }
1

There are 1 best solutions below

0
On

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