Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Eclipselink Shared Cache duplicate entities

Could you include the SQL log, and the code for your test methods.

It seems you might be corrupting your object clones.  My guess would be you
are keeping the new Need on the test client which does not have any assign
ids, then every time you merge() it, you are adding new NeedProducts, as
their id is null.  You need to return the inserted/updated objects back to
the client.



Mahipal wrote:
> 
> 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
> 
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
> 
> 


-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://old.nabble.com/Eclipselink-Shared-Cache-duplicate-entities-tp27793000p27837418.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top