| Summary: | The Versionfield is neither updated correctly across different VM instances nor are the fields are updated | ||||||
|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Christoph Laeubrich <laeubi> | ||||
| Component: | Eclipselink | Assignee: | Nobody - feel free to take it <nobody> | ||||
| Status: | CLOSED INVALID | QA Contact: | |||||
| Severity: | major | ||||||
| Priority: | P3 | CC: | tom.ware | ||||
| Version: | unspecified | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
Created attachment 203028 [details]
Testcase for problem
Includes:
- Annotated file and persistence.xml
- testcase bundle (source included as well)
Comment on attachment 203028 [details]
Testcase for problem
Base class for example
@MappedSuperclass
public class PersitentBase {
@Version
private long version;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Transient
private boolean incremented;
/**
* @return the current value of id
*/
public long getID() {
return id;
}
/**
* @return the current value of version
*/
public long getVersion() {
return version;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "PersitentBase [version=" + version + ", id=" + id + "]";
}
/**
*
*/
public void incrementVersion() {
if (!incremented) {
version++;
incremented = true;
}
}
}
The reason you are seeing this issue is that you are doing a primary key lookup. In the default case, this will return an object from the cache. You have numerous options. - You can do a refresh - You can use a refresh query hint - There are a number of cache configuration options that will alleviate this issue depending on your goal (cache type and size, isolated cache etc.) (In reply to comment #3) Hi Tom, thank for your comment. > The reason you are seeing this issue is that you are doing a primary key > lookup. In the default case, this will return an object from the cache. I'm a little bit confused. Since I'm closing the EntityManager shouldn't it assume that all chached entries are invalidated? > You have numerous options. > - You can do a refresh Calling refresh on the object throws an exception since the object is detached. Selecting the object (and thus reattaching it) and the calling refresh works, but this don't feels right. > - You can use a refresh query hint Is this possible in a portable way or do I need to use EclipseLink specific Annotations? > - There are a number of cache configuration options that will alleviate this > issue depending on your goal (cache type and size, isolated cache etc.) My goal is the following: Many distributed clients loading objects and holding a local (detached) copy. Everytime the user tries to edit the Object is reloaded from the database and the saved (which failed if another client has edited this object because of incremented version number) Is this the intended behaviour that detached objects are still fetched from the cache? Sounds confusing to me or do i get something wrong? > The reason you are seeing this issue is that you are doing a primary key > lookup. In the default case, this will return an object from the cache. I'm a little bit confused. Since I'm closing the EntityManager shouldn't it assume that all chached entries are invalidated? - There is a 2nd level cache. It is, for all intents and purposes, on the EntityManagerFactory. This is where you are getting the object from. > You have numerous options. > - You can do a refresh Calling refresh on the object throws an exception since the object is detached. Selecting the object (and thus reattaching it) and the calling refresh works, but this don't feels right. - try the refresh query hint. It can either be provided as a hint for your JPQL or Criteria Query, or in the optional list of properties in the find method: http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Refresh > - You can use a refresh query hint Is this possible in a portable way or do I need to use EclipseLink specific Annotations? - Query hints are in the JPA spec and complete portable - see above for details about EclipseLink's refresh hint. > - There are a number of cache configuration options that will alleviate this > issue depending on your goal (cache type and size, isolated cache etc.) My goal is the following: Many distributed clients loading objects and holding a local (detached) copy. Everytime the user tries to edit the Object is reloaded from the database and the saved (which failed if another client has edited this object because of incremented version number) Is this the intended behaviour that detached objects are still fetched from the cache? Sounds confusing to me or do i get something wrong? - That is the goal of refresh. The cache provides quite alot of performance benefit when reading and when tied with a good locking policy is very powerful. If, however, you would like you cache tied more closely to your EntityManager - rather than your EntityManagerFactory, you can use our isolated cache setting. Take a look at this: http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Entity_Caching The entry on: "eclipselink.cache.shared.default" is a good start. (In reply to comment #5) Hi Tom, thanks for your explanation I was not aware that the cache was bound to the EMF and not to the EM, sorry for the inconvenience opening this issue :) I found out that with JPA 2.0 @Cacheable(false) annotation the caching could be switched of thanks for taking my head in the right direction, I think this will work for me until I have understand the whole cache configuration thing :) The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
Build Identifier: 2.3.0.v20110604-r9504 When runnung two independent VM instances (A & B) with a versioned entity the following szenario fails: - Load the entity in both instances (for example by ID) - update it in instance A - (reload) it in instance B What happens: B keeps its old version value. Example Logoutput: Instance A: Loaded Literatur [fields={}, name=Test 2, typ=MISC, bibliothek_id=1, PersitentBase [version=3, id=1]] Instance B: Loaded Literatur [fields={}, name=Test 2, typ=MISC, bibliothek_id=1, PersitentBase [version=3, id=1]] Instance A: Saved Literatur [fields={}, name=Test 0, typ=MISC, bibliothek_id=1, PersitentBase [version=4, id=1]] Instance B: Loaded Literatur [fields={}, name=Test 2, typ=MISC, bibliothek_id=1, PersitentBase [version=3, id=1]] This only happens when the Object already was loaded! For example other Szenario: Instance A: Loaded Literatur [fields={}, name=Test 0, typ=MISC, bibliothek_id=1, PersitentBase [version=5, id=1]] Saved Literatur [fields={}, name=Test 0, typ=MISC, bibliothek_id=1, PersitentBase [version=6, id=1]] Saved Literatur [fields={}, name=Test 1, typ=MISC, bibliothek_id=1, PersitentBase [version=7, id=1]] Saved Literatur [fields={}, name=Test 2, typ=MISC, bibliothek_id=1, PersitentBase [version=8, id=1]] Instance B: Loaded Literatur [fields={}, name=Test 2, typ=MISC, bibliothek_id=1, PersitentBase [version=8, id=1]] Reproducible: Always Steps to Reproduce: See above and attached example files