eclipselink 2.0 and weblogic 10.3.2 integration [message #508909] |
Wed, 20 January 2010 16:54 |
Miroslav Messages: 4 Registered: January 2010 Location: Belgrade |
Junior Member |
|
|
Hy.
We are using weblogic server 10.3.2 and eclipselink 2.0. Actually we are trying to migrate our application to this version of eclipselink.
Now we have big problem because merge operation of entity manager is not propagated correctly on collection.
Usecase is like this
We have entity Master which have collection of entities Detail.
Object master have method change, and within this method new Instance of detail is created and stored in collection.
After that we invoke merge operation of entity manager. When we put second entity in collection an invoke merge, this error occures.
Exception Description: Null primary key encountered in unit of work clone com.ms.entities.Detail@af1b26.
at org.eclipse.persistence.exceptions.ValidationException.nullP rimaryKeyInUnitOfWorkClone(ValidationException.java:1403)
at org.eclipse.persistence.descriptors.changetracking.DeferredC hangeDetectionPolicy.calculateChanges(DeferredChangeDetectio nPolicy.java:106)
at org.eclipse.persistence.descriptors.changetracking.Attribute ChangeTrackingPolicy.calculateChangesForExistingObject(Attri buteChangeTrackingPolicy.java:47)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cal culateChanges(UnitOfWorkImpl.java:624)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1495)
Everything is fine if do not invoke em.merge(master);
I have looked at the source code and in eclipse debuger I saw that eclipselink missed to assign ID to new entity. Actually hash map for new entities was empty.
I have created simple project in JDeveloper 11g Release 1 to support this use case.
You can download it from http://www.keepandshare.com/doc/view.php?id=1693335&da=y
Session bean is MasterDetailSessionEJB1Bean, and client is MasterDetailSessionEJB1Client.
MasterDetailSessionEJB1Bean have method
public Master chamgeNameOfMaster(Master master, String newName){
master = em.find(Master.class, master.getId());
master.change(newName);
master = em.merge(master);
return master;
}
The error doesn't occur if we delete line master = em.merge(master).
Or if the entities cache is turned of with properties in persistence.xml
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.type.default" value="NONE"/>
I will be very happy if someone tells me where is problem.
--
Thanks,
Miroslav
[Updated on: Wed, 20 January 2010 16:58] Report message to a moderator
|
|
|
|
Re: eclipselink 2.0 and weblogic 10.3.2 integration [message #509206 is a reply to message #508909] |
Thu, 21 January 2010 16:47 |
|
Looks like it is thinking a new object is an existing object, somehow. What does your change() method do, and how is the object mapped?
If disabling the cache fixes the issue, my guess would be you are somehow getting an object with a null or 0 primary key put into the cache, and then the merge thinks a new object is this existing object. You can check the cache before this operation to verify this, but the question is what you are doing before this that could be getting an object will a null or 0 id put into the cache?
James : Wiki : Book : Blog : Twitter
|
|
|
Re: eclipselink 2.0 and weblogic 10.3.2 integration [message #509559 is a reply to message #509206] |
Fri, 22 January 2010 22:08 |
Miroslav Messages: 4 Registered: January 2010 Location: Belgrade |
Junior Member |
|
|
Thank you for replies.
I agree with Duog. Entities should not be merged, after they become managed. It is overhead. But it is not forbidden by JPA specification.
Anyway, I think that I have solved the problem . I didn't mention earlier that, in SE environment everything was fine. Problem appears only in EE (weblogic 10.3.2).
After 2 days of debugging through eclipselink source code and reading documentation I discovered that execution wasn't the same. On application server feature eclipselink.weaving.changetracking was enabled by default. And this thing caused problems.
Now I have this line in my persistence.xml
<property name="eclipselink.weaving.changetracking" value="false"/>
and my example works fine.
Changetracking looks me like nice feature but there is collision with merge operation. By changetracking feature, new entity (Detail) was placed on server cache immediately after it was added in collection in Master entity (method change in Master entity). After that, merge operation didn't assigne sequence into id field of new Detail entity........ because it wasn't new! New entity was already in cache, thanks to changetracking feature.
Validation during flushing discovered that one entity don't have id, and BUM. Quote: | Null primary key encountered in unit of work clone.....
|
Master entity
@Entity
@Table(name = "MASTER")
public class Master implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")
@SequenceGenerator(name = "ID_GENERATOR", sequenceName = "ID_GENERATOR")
private Long id;
@Version
private Long version;
private String name;
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY, mappedBy="master")
protected List<Detail> details;
public Master() {
details = new ArrayList<Detail>();
}
public void change(String newName){
Detail detail = new Detail(getName(), this);
details.add(detail);
this.name = newName;
}
//setters and getters
}
Detail entity
public class Detail implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")
@SequenceGenerator(name = "ID_GENERATOR", sequenceName = "ID_GENERATOR")
private Long id;
@Version
private Long version;
private String name;
@ManyToOne
@JoinColumn (name="MASTER_ID")
private Master master;
public Detail() {
}
public Detail(String newName, Master master) {
this.name = newName;
this.master = master;
}
//setters and getters
}
Method in session bean
public Master chamgeNameOfMaster(Master master, String newName){
master = em.find(Master.class, master.getId());
master.change(newName);
master = em.merge(master);
return master;
}
[Updated on: Fri, 22 January 2010 22:56] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.03612 seconds