[
https://issues.jboss.org/browse/ISPN-1140?page=com.atlassian.jira.plugin....
]
Steven Newson updated ISPN-1140:
--------------------------------
Description:
The implementation of {{setValue()}} in {{TransientMortalCacheEntry}} is as follows
{code:java}
public Object setValue(Object value) {
return cacheValue.maxIdle;
}
{code}
This leads to problems in the {{DefaultDataContainer}} as the following {{put()}} code has
no effect:
{code:java}
public void put(Object k, Object v, long lifespan, long maxIdle) {
InternalCacheEntry e = entries.get(k);
if (e != null) {
e.setValue(v);
InternalCacheEntry original = e;
e = entryFactory.update(e, lifespan, maxIdle);
// we have the same instance. So we need to reincarnate.
if(original == e) {
e.reincarnate();
}
} else {
// this is a brand-new entry
e = entryFactory.createNewEntry(k, v, lifespan, maxIdle);
}
entries.put(k, e);
}
{code}
The effect of this for me is that when I am not in a JTA enviroment and I take the
following steps via Hibernate the result is not cached correctly:
- Insert record into table via Hibernate
- Reload record by its ID
- Change non-ID field on the record
- Update the record via Hibernate
- Reload the record by its ID
- Check that the value reloaded matches the updated value
The 2nd level cache always returns the first inserted record rather than the updated one.
Each Hibernate access is inside its own transaction.
I fixed this locally by overriding the class in the classpath, replacing the
{{setValue()}} method with the following implementation:
{code:java}
public Object setValue(Object value) {
Object original = cacheValue.value;
cacheValue.value = value;
return original;
}
{code}
Which also corresponds to the (misspelled :)) Javadoc:
{noformat}Sets the value of the entry, returing the previous value{noformat}
was:
The implementation of {{setValue()}} in {{TransientMortalCacheEntry}} is as follows
{code:java}
public Object setValue(Object value) {
return cacheValue.maxIdle;
}
{code}
This leads to problems in the {{DefaultDataContainer}} as the following {{put()}} code has
no effect:
{code:java}
public void put(Object k, Object v, long lifespan, long maxIdle) {
InternalCacheEntry e = entries.get(k);
if (e != null) {
e.setValue(v);
InternalCacheEntry original = e;
e = entryFactory.update(e, lifespan, maxIdle);
// we have the same instance. So we need to reincarnate.
if(original == e) {
e.reincarnate();
}
} else {
// this is a brand-new entry
e = entryFactory.createNewEntry(k, v, lifespan, maxIdle);
}
entries.put(k, e);
}
{code}
The effect of this for me is that the following steps via Hibernate don't work:
- Insert record into table via Hibernate
- Reload record by its ID
- Change non-ID field on the record
- Update the record via Hibernate
- Reload the record by its ID
- Check that the value reloaded matches the updated value
The 2nd level cache always returns the first inserted record rather than the updated one.
Each Hibernate access is inside its own transaction.
I fixed this locally by overriding the class in the classpath, replacing the
{{setValue()}} method with the following implementation:
{code:java}
public Object setValue(Object value) {
Object original = cacheValue.value;
cacheValue.value = value;
return original;
}
{code}
Which also corresponds to the (misspelled :)) Javadoc:
{noformat}Sets the value of the entry, returing the previous value{noformat}
TransientMortalCacheEntry has incorrect implementation of setValue()
--------------------------------------------------------------------
Key: ISPN-1140
URL:
https://issues.jboss.org/browse/ISPN-1140
Project: Infinispan
Issue Type: Bug
Components: Core API
Affects Versions: 4.2.1.FINAL, 5.0.0.CR3
Reporter: Steven Newson
Assignee: Galder Zamarreño
Fix For: 5.0.0.CR4, 5.0.0.FINAL
The implementation of {{setValue()}} in {{TransientMortalCacheEntry}} is as follows
{code:java}
public Object setValue(Object value) {
return cacheValue.maxIdle;
}
{code}
This leads to problems in the {{DefaultDataContainer}} as the following {{put()}} code
has no effect:
{code:java}
public void put(Object k, Object v, long lifespan, long maxIdle) {
InternalCacheEntry e = entries.get(k);
if (e != null) {
e.setValue(v);
InternalCacheEntry original = e;
e = entryFactory.update(e, lifespan, maxIdle);
// we have the same instance. So we need to reincarnate.
if(original == e) {
e.reincarnate();
}
} else {
// this is a brand-new entry
e = entryFactory.createNewEntry(k, v, lifespan, maxIdle);
}
entries.put(k, e);
}
{code}
The effect of this for me is that when I am not in a JTA enviroment and I take the
following steps via Hibernate the result is not cached correctly:
- Insert record into table via Hibernate
- Reload record by its ID
- Change non-ID field on the record
- Update the record via Hibernate
- Reload the record by its ID
- Check that the value reloaded matches the updated value
The 2nd level cache always returns the first inserted record rather than the updated one.
Each Hibernate access is inside its own transaction.
I fixed this locally by overriding the class in the classpath, replacing the
{{setValue()}} method with the following implementation:
{code:java}
public Object setValue(Object value) {
Object original = cacheValue.value;
cacheValue.value = value;
return original;
}
{code}
Which also corresponds to the (misspelled :)) Javadoc:
{noformat}Sets the value of the entry, returing the previous value{noformat}
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira