[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[eclipselink-users] Eclipselink Shared Cache duplicate entities
|
Title: Eclipselink Shared Cache duplicate entities
Hello All,
It seems we have a problem while using shared cache in EclipseLink. We are using version 2.0.1 of EclipseLink
We have two Entities Need and NeedProduct (code snippet as below)
@SuppressWarnings("serial")
@Entity
@Table(name = "XXXX", schema = "XXX")
@org.eclipse.persistence.annotations.TypeConverter(name = "NVARCHAR2", dataType = org.eclipse.persistence.platform.database.oracle.NString.class, objectType = String.class)
public class Need implements Serializable {
public Need() {
}
/**
* primary key
*/
@Id
@GeneratedValue(generator = "uuid-string")
@Column(name = "XMI_INSTANCE_TGUID")
private String uid = null;
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
@OneToMany(mappedBy = "need", fetch = FetchType.EAGER, cascade = {
CascadeType.REFRESH, CascadeType.ALL})
private List<NeedProduct> needProduct = new ArrayList<NeedProduct>();
public void setNeedProduct(
List<NeedProduct> needProduct) {
this.needProduct = needProduct;
}
public List<NeedProduct> getNeedProduct() {
return needProduct;
}
public void addNeedProduct(
NeedProduct listElement) {
listElement.setNeed(this);
needProduct.add(listElement);
}
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof Need)) {
return false;
}
Need anotherDataObject = (Need) object;
if ((uid == null && anotherDataObject.uid != null)
|| (uid != null && anotherDataObject.uid == null))
return false;
if (uid != null && !uid.equals(anotherDataObject.uid))
return false;
return true;
}
/**
* Creates a String representing the target with all attribute values shown.
*
* @return a String representing the state of the target
*/
@Override
public String toString() {
StringBuffer result = new StringBuffer(500);
if (uid == null) {
result.append("null");
} else {
result.append(uid.toString());
}
return result.toString();
}
}
@SuppressWarnings("serial")
@Entity
@Table(name = "XXXX", schema = "XXX")
@org.eclipse.persistence.annotations.TypeConverter(name = "NVARCHAR2", dataType = org.eclipse.persistence.platform.database.oracle.NString.class, objectType = String.class)
public class NeedProduct implements Serializable {
public NeedProduct() {
}
@ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = {
CascadeType.REFRESH, CascadeType.MERGE})
@JoinColumn(name = "XMI_NEED_TGUID", referencedColumnName = "XMI_INSTANCE_TGUID")
private Need need = null;
public void setNeed(Need need) {
this.need = need;
}
public Need getNeed() {
return need;
}
@Id
@GeneratedValue(generator = "uuid-string")
@Column(name = "XMI_INSTANCE_TGUID")
private String uid = null;
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof NeedProduct)) {
return false;
}
NeedProduct anotherDataObject = (NeedProduct) object;
if ((uid == null && anotherDataObject.uid != null)
|| (uid != null && anotherDataObject.uid == null))
return false;
if (uid != null && !uid.equals(anotherDataObject.uid))
return false;
return true;
}
@Override
public String toString() {
StringBuffer result = new StringBuffer(500);
if (uid == null) {
result.append("null");
} else {
result.append(uid.toString());
}
return result.toString();
}
}
Snippet from persistence.xml
<property name="eclipselink.weaving" value="true"/>
<property name="eclipselink.weaving.eager" value="false"/>
<property name="eclipselink.cache.type.default" value="SoftWeak"/>
<property name="eclipselink.cache.size.default" value="5000"/>
<property name="eclipselink.cache.shared.default" value="true"/>
<property name="eclipselink.flush-clear.cache" value="DropInvalidate"/>
Here is the snippet from GenericDAOJPAImpl
public T update(T entity) {
long startTime = System.currentTimeMillis();
try {
entity = entityManager.merge(entity);
entityManager.flush();
entityManager.refresh(entity);
return entity;
} finally {
long duration = System.currentTimeMillis() - startTime;
if (duration > 500) {
LOGGER.info("Database Access duration = " + duration
+ "ms with update entity");
}
}
}
When I try to test the following scenario, it gives incorrect results
Test 1. updateNeed --> This will insert Need entity with 3 NeedProduct
Test 2. getNeed --> This will return Need entity with exact 3 NeedProduct (Correct Behavior)
Test 3. updateNeedProduct --> This Updates one of the NeedProduct received from step2 (Please note this is actual update on NeedProduct entity and not through update of its parent i.e. Need)
Test 4. getNeed --> Now this returns Need entity with 10 NeedProduct (Incorrect Behavior), DB still has 3 NeedProduct rows
In test 3, instead of updating NeedProduct directly if I update NeedProduct through Need instance(meaning calling updateNeed() instead of updateNeedProduct()) the behavior is correct
Also when I change <property name="eclipselink.cache.shared.default" value="true"/> this to <property name="eclipselink.cache.shared.default" value="false"/> everything works fine.
Could someone please help to find the reasoning of this incorrect behavior?
Thanks, Mahipal