[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
| 
RE: [eclipselink-users] Eclipselink Shared Cache duplicate entities
 | 
Hello 
James,
Thanks for the reply. Here are some more details.
Test 
Methods :
1. Test Method for 
updateNeed
        
public void test_updateNeed() throws Exception 
{
        
        System.out.println("start 
test_updateNeed \n");
        
        Need_1_0 beanRemote = 
lookupService();
        
        UpdateNeed_Parameters 
updateNeed_Parameters = 
provide_UpdateNeed_Parameters();
        
        Need testNewInstance = 
getNeedInstance();
        
        System.out.println("Need input " + 
testNewInstance + "\n");
        
        Need testNewResult = 
beanRemote
        
        
        
        .updateNeed(testNewInstance, 
updateNeed_Parameters.businessUnit);
        
        
assertNotNull(testNewResult);
        
        
storeNeedInstance(testNewResult);
        
        System.out.println("Need " + 
testNewResult);
        
}
       
        
public Need getNeedInstance() 
{
        
        if (needInstance != null) return 
needInstance;
        Need need = new 
Need();
        need.setComment("DDD" + 
Integer.toString(updatesNeed));
        
need.setBUID("0012");
        
need.setPartner(partnerUUID);
        
need.setLifeCycleStatus(LifeCycleStatus.ACTIVE);
        
need.setType("AAA");
        
need.setStatus("CCC");
        
NeedProduct needProduct = new 
NeedProduct();
        
needProduct.setLifeCycleStatus(LifeCycleStatus.ACTIVE);
        
needProduct.setNeedProductCode("P2");
        
need.addNeedProduct(needProduct);
        
        return need;
    
}
       
    
public void storeNeedInstance(Need instance) 
{
            
needInstance = 
instance;       
            
System.out.println("Number Of Need Products : " + 
needInstance.getNeedProduct().size());
    }    
2. Test method for 
updateNeedProduct
        
public void test_updateNeedProduct() throws Exception 
{
        
        System.out.println("start 
test_updateNeedProduct \n");
        
        Need_1_0 beanRemote = 
lookupService();
        
        NeedProduct testNewInstance = 
getNeedProductInstance();
        
        System.out.println("NeedProduct input 
" + testNewInstance + "\n");
        
        NeedProduct testNewResult = 
beanRemote
        
        
        
        
.updateNeedProduct(testNewInstance);
        
        
assertNotNull(testNewResult);
        
        
storeNeedProductInstance(testNewResult);
        
        System.out.println("NeedProduct " + 
testNewResult);
        
}
       
        
public NeedProduct getNeedProductInstance() 
{
        
        if (needProductInstance != null) 
return needProductInstance;
        
        
         
needInstance.getNeedProduct().get(0).setCreatedByPID("A134678");
        
        return 
needInstance.getNeedProduct().get(0);
        
}
       
        
public void 
storeNeedProductInstance(
        
        
        NeedProduct instance) 
{
        
        
        needProductInstance = instance; 
       
        
}
       
3. test 
Methods for getNeed
        
public void test_getNeed() throws Exception 
{
        
        System.out.println("start 
test_getNeed \n");
        
        Need_1_0 beanRemote = 
lookupService();
        
        Need testInstance = 
getNeedInstance();
        
        GetNeed_Parameters getNeed_Parameters 
= provide_GetNeed_Parameters();
        
        Need testResult = 
beanRemote
        
        
        
        
.getNeed(getNeed_Parameters.id);
        
        
assertNotNull(testResult);
        
        
assertNotNull(testResult.getUid());
        
        if (testInstance.getBUID() != 
null)
        
        
        assertEquals(testInstance.getBUID(), 
testResult.getBUID());
        
        if (testInstance.getPartner() != 
null)
        
        
        
assertEquals(testInstance.getPartner(), 
testResult.getPartner());
        
        if (testInstance.getComment() != 
null)
        
        
        
assertEquals(testInstance.getComment(), 
testResult.getComment());
        
        if (testInstance.getType() != 
null)
        
        
        assertEquals(testInstance.getType(), 
testResult.getType());
        
        if (testInstance.getStatus() != 
null)
        
        
        
assertEquals(testInstance.getStatus(), 
testResult.getStatus());
        
        
storeNeedInstance(testResult);
        
        System.out.println("end test_getNeed 
\n");
        
}
       
        
public GetNeed_Parameters provide_GetNeed_Parameters() 
{
        
        GetNeed_Parameters x = new 
GetNeed_Parameters();
        
        x.id = 
needInstance.getUid();
        
        return 
x;
        
}      
And here are the SQL 
statements in the sequence as they appear in the logs.
 
INSERT INTO XXXX.SNEED_NEED_VAMI#00 
(XMI_INSTANCE_TGUID, XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, 
XMU_NEED_STATUS, XMD_CREATED_AT_TSMP, XMI_PARTNER_TGUID, XMU_NEED_COMMENT, 
XMU_CURRENT_OWNING_BUID, XMU_NEED_TYPE, XMU_INSTANCE_MUT_SEQNR) VALUES (?, ?, ?, 
?, ?, ?, ?, ?, ?, ?)
 bind => [BF18D9430A8F440A97FAE783E9E4A8A2, 2, 
A448579, CCC, null, 717B452D7B2B43BDE04400144FEBBD1C, DDD1, 0012, AAA, 
1]
 
INSERT INTO XXXX.SNEED_NEEDP_VAMI#00 
(XMI_INSTANCE_TGUID, XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, 
XMD_CREATED_AT_TSMP, XMI_NEED_PRODUCT_CD, XMU_INSTANCE_MUT_SEQNR, 
XMI_NEED_TGUID) VALUES (?, ?, ?, ?, ?, ?, ?)
 bind => 
[A78E9E5B2901458B8D0DC41435A22CD0, 2, A448579, null, P2, 1, 
BF18D9430A8F440A97FAE783E9E4A8A2]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMU_NEED_STATUS, 
XMD_CREATED_AT_TSMP, XMI_PARTNER_TGUID, XMU_NEED_COMMENT, 
XMU_CURRENT_OWNING_BUID, XMU_NEED_TYPE, XMU_INSTANCE_MUT_SEQNR FROM 
XXXX.SNEED_NEED_VAMI#00 WHERE (XMI_INSTANCE_TGUID = ?)
 bind => 
[BF18D9430A8F440A97FAE783E9E4A8A2]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMD_CREATED_AT_TSMP, 
XMI_NEED_PRODUCT_CD, XMU_INSTANCE_MUT_SEQNR, XMI_NEED_TGUID FROM 
XXXX.SNEED_NEEDP_VAMI#00 WHERE (XMI_NEED_TGUID = ?)
 bind => 
[[B@1662318]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMU_NEED_STATUS, 
XMD_CREATED_AT_TSMP, XMI_PARTNER_TGUID, XMU_NEED_COMMENT, 
XMU_CURRENT_OWNING_BUID, XMU_NEED_TYPE, XMU_INSTANCE_MUT_SEQNR FROM 
XXXX.SNEED_NEED_VAMI#00 WHERE (XMI_INSTANCE_TGUID = ?)
 bind => 
[[B@8a3bf2]
 
UPDATE XXXX.SNEED_NEEDP_VAMI#00 SET 
XMU_INSTANCE_LIFECYCLE_STATUS = ?, XMU_INSTANCE_MUT_SEQNR = ? WHERE 
((XMI_INSTANCE_TGUID = ?) AND (XMU_INSTANCE_MUT_SEQNR = ?))
 bind => 
[7, 2, A78E9E5B2901458B8D0DC41435A22CD0, 1]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMD_CREATED_AT_TSMP, 
XMI_NEED_PRODUCT_CD, XMU_INSTANCE_MUT_SEQNR, XMI_NEED_TGUID FROM 
XXXX.SNEED_NEEDP_VAMI#00 WHERE (XMI_INSTANCE_TGUID = ?)
 bind => 
[A78E9E5B2901458B8D0DC41435A22CD0]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMU_NEED_STATUS, 
XMD_CREATED_AT_TSMP, XMI_PARTNER_TGUID, XMU_NEED_COMMENT, 
XMU_CURRENT_OWNING_BUID, XMU_NEED_TYPE, XMU_INSTANCE_MUT_SEQNR FROM 
XXXX.SNEED_NEED_VAMI#00 WHERE (XMI_INSTANCE_TGUID = ?)
 bind => 
[[B@6faf61]
 
SELECT XMI_INSTANCE_TGUID, 
XMU_INSTANCE_LIFECYCLE_STATUS, XMU_CREATED_BY_PID, XMD_CREATED_AT_TSMP, 
XMI_NEED_PRODUCT_CD, XMU_INSTANCE_MUT_SEQNR, XMI_NEED_TGUID FROM 
XXXX.SNEED_NEEDP_VAMI#00 WHERE (XMI_NEED_TGUID = ?)
 bind => 
[[B@63359c]
 
 
Another point to note 
is, this behaviour is reproducible even in application and not limited to tests. 
And I think if you see the code in GenericDAOJPAImpl, it refreshes the entity 
after it is merged and return the same.
public
 T update(T entity) 
{ 
entity = 
entityManager.merge(entity);
entityManager.flush();
entityManager.refresh(entity);
return entity; 
}
Thanks & Regards, 
Mahipal
-----Original Message-----
From: 
eclipselink-users-bounces@xxxxxxxxxxx [mailto:eclipselink-users-bounces@xxxxxxxxxxx] 
On Behalf Of James Sutherland
Sent: Tuesday, March 09, 2010 4:38 PM
To: 
eclipselink-users@xxxxxxxxxxx
Subject: 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.
_______________________________________________
eclipselink-users 
mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users