Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Very strange "primary key [null]" validation exception ("primary key [null]" exception appear where it should not)
Very strange "primary key [null]" validation exception [message #893590] Wed, 04 July 2012 13:48 Go to previous message
Rodion Missing name is currently offline Rodion Missing name
Messages: 8
Registered: September 2009
Junior Member
I'm using eclipselink v 2.3.2 (supplied with glassfish v.3.2)
I've got this stack while trying to merge object graph into database:

Exception [EclipseLink-7197] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone [com.hospitality.hp.osloproject.entities.contacts.info.PhoneContactInfo@75c191a7], primary key [null]. Set descriptors IdValidation or the "eclipselink.id-validation" property.
	at org.eclipse.persistence.exceptions.ValidationException.nullPrimaryKeyInUnitOfWorkClone(ValidationException.java:1439)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:107)
	at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:54)


My entities model looks like these:
@Entity
public class PhoneContactInfo {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PROFILE_ENTITES")
  private Integer id;
  ...
}

@Entity
public class PersonContactableProfile extends ContactableProfile{
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PROFILE_ENTITES")
  private Integer id;
  
  @OneToOne(cascade = {CascadeType.ALL}, orphanRemoval = true, optional = true)
  private PhoneContactInfo phoneInfo;

  @OneToOne(optional = false, cascade = CascadeType.ALL)
  private Person person;
  ...
}

@Entity
public class UserContact {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PROFILE_ENTITES")
  private Integer id;
  
  @OneToOne(optional = false, orphanRemoval = false, fetch = FetchType.EAGER)
  private ContactableProfile contactable;

  @ManyToOne(optional = false, fetch = FetchType.EAGER)
  private Person personOwner;

  ...
}

@Entity
public class PersonToPersonLink {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PROFILE_ENTITES")
  private Integer id;
  
  @ManyToOne(fetch = javax.persistence.FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
  private Person relative;

  @ManyToOne(fetch = javax.persistence.FetchType.LAZY)
  private Person user;
  
  ...
}

@Entity
public class Person {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_PROFILE_ENTITES")
  private Integer id;

  @OneToMany(mappedBy = "personOwner", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  private Set<UsersContact> contacts;

  @OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true, fetch = FetchType.LAZY)
  private Set<UserRelativeLink> relativeLinks;

  @OneToOne(optional = false, cascade = {CascadeType.ALL}, mappedBy = "person", fetch = FetchType.LAZY)
  private PersonContactableProfile personContactableProfile;

  ...
}


Every Person may have PersonContactable which is basically set of "ways to contact person" (e.g. phone number) - there is other types of contactable profiles in system, but this does not matter now. Every person can also may have collection of contacts and collection of relatives. UserContact entity, essentially, is record in one's contacts list. PersonToPersonLink keep link between two persons (e.g. relative). I have two Person instances, lets say Person1 and Person2. Person2 is already in Persons1's relstiveLinks collection (all data in database already). Then I take Person1, add new UserContact that points to Person2 PersonContactableProfile and also add new PhoneContactInfo to PersonContactableProfile of Person2 - I've got exception described above while saving Person1 graph (entityManager.merge(Person2)).

While investigating that issue i've found out why it happening - PhoneContactInfo instance added to cloneMapping collection of UnitOfWorkImpl twice!
First time during mapping traversal through contacts collection and second time during mapping traversal through relativeLinks collection. I do not understand if it's a bug? I also find out that line in MergeManager source code (trunk):

...
            Object registeredObject = unitOfWork.internalRegisterObject(clone, descriptor);//should use cloneAndRegisterNewObject to avoid the exist check
...


Addition of second copy of PhoneContactInfo to cloneMapping collection happening exactly during existence check.

Can someone tell me how I can fix this behaviour?
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic:difference between PESSIMISTIC_WRITE and read?
Next Topic:Postgresql NULLS FIRST Order by
Goto Forum:
  


Current Time: Wed May 22 02:04:28 EDT 2013

Powered by FUDForum. Page generated in 0.01812 seconds