[
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