Home » Eclipse Projects » EclipseLink » PK Violation on Many-to-One Child Record(Child is not changed, but is being persisted with PK violation)
PK Violation on Many-to-One Child Record [message #842801] |
Thu, 12 April 2012 12:13  |
Eclipse User |
|
|
|
I have an entity, Journal, which has a Many-to-One relationship with a second entity, DeliveryType. The mapping is expressed as:
@Entity
@Table(name = "JOURNAL")
public class Journal implements Serializable, Comparable<Journal> {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "DELIVERY_TYPE_ID")
private DeliveryType deliveryType;
//...excluded...
}
DeliveryType is merely a static look-up table with 6 values. It should never be persisted. Its ID should just be written as a foreign key to the Journal table.
@Entity
@Table(name="DELIVERY_TYPE")
@NamedQueries({
@NamedQuery(name=DeliveryType.DISPLAYABLE,
query="select s from DeliveryType s where s.isDisplayable = 'Y'" ),
@NamedQuery(name=DeliveryType.DUPE_CHECK,
query="select s from DeliveryType s where lower(s.description)=lower(:description)" )
})
public class DeliveryType implements Serializable, Comparable<DeliveryType> {
//...omitted...
}
The project previously used TopLink, but I don't think the conversion is responsible for the odd behavior. The problem is that when parent entity, Journal is changed (assigned a different DeliveryType), EclipseLink seems to think that the DeliveryType object is a brand new object and does an INSERT op on it, causing a primary key violation. This is suddenly happening with many of our look-up-only entities.
Is there some kind of caching going on that detaches these entities from the PersistenceManager somehow? Why does EclipseLink think they are new and try to save them?
Details:
===============
EclipseLink 2.3
JPA 2.0
JDeveloper
WebLogic 10.3.5
Oracle 9, Thin Driver, Non-XA DataSources
Sun JDK 1.6
|
|
| |
Re: PK Violation on Many-to-One Child Record [message #846685 is a reply to message #846668] |
Mon, 16 April 2012 13:19   |
Eclipse User |
|
|
|
James,
Thanks so much for taking the time to look at this for me!!
Sorry to give the wrong impression. The DeliveryType IS a managed object. It is loaded from the table of just 6 rows, and referenced from the Journal object. The relationship graph being persisted is:
Case
--Journal
--DeliveryType
--Journal
--DeliveryType
--Journal
--DeliveryType
--Journal
--DeliveryType
So a single case is persisted. A case can have many Journal entries. Each Journal Entry has just 1 required DeliveryType, which is assigned from just 6 possible values (such as FAX, HAND DELIVERY, etc). The question is, when we call:
entityManager.persist(case);
Why is it saving Case, Saving each Journal, and trying to insert the DeliveryType object into the database as though they are entirely new objects?
Here is the error console output.
Query: WriteObjectQuery(com.whatever.DeliveryType@855b9a)],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=1,seconds left=30,XAServerResourceInfo[my_app_DefaultDomain]=(ServerResourceInfo[my_app_DefaultDomain]=(state=rolledback,assigned=DefaultServer),xar=weblogic.jdbc.wrapper.JTSEmulateXAResourceImpl@9df864,re-Registered = false),SCInfo[DefaultDomain+DefaultServer]=(state=rolledback),properties=({weblogic.transaction.name=[EJB com.whatever.service.CaseSessionBean.saveAndReopen()], weblogic.jdbc.remote.my_app=t3://10.10.1.1:7101}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=DefaultServer+10.10.1.1:7101+DefaultDomain+t3+, XAResources={my_app_DefaultDomain, document_storage_app_DefaultDomain, WSATGatewayRM_DefaultServer_DefaultDomain},NonXAResources={})],CoordinatorURL=DefaultServer+10.10.1.1:7101+DefaultDomain+t3+): weblogic.transaction.RollbackException: Unexpected exception in beforeCompletion: sync=org.eclipse.persistence.transaction.JTASynchronizationListener@1ad09a1
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (MY_DATA.DELIVERY_TYPE_PK) violated
Error Code: 1
Call: INSERT INTO my_data.DELIVERY_TYPE (DELIVERY_TYPE_ID, DESCRIPTION, DISPLAYABLE) VALUES (?, ?, ?)
bind => [2, FAX, Y]
The essential entity code and annotations are as so:
// Case to Journal
@Entity
@Table(name = "CASE")
@NamedStoredProcedureQuery(
name="PROCESS_CASE_PROCEDURE",
procedureName="processCase",
returnsResultSet=false,
parameters={
@StoredProcedureParameter(queryParameter="param1",name="x",direction=Direction.OUT,type=String.class)
}
)
public class Case implements Serializable, Comparable<EoasCase> {
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "CASE_ID" )
@OrderBy("entryDate")
private List<Journal> journals = new ArrayList<Journal>();
}
@Entity
@Table(name = "JOURNAL")
public class Journal implements Serializable, Comparable<Journal> {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "DELIVERY_TYPE_ID")
private DeliveryType deliveryType;
}
@Entity
@Table(name="DELIVERY_TYPE")
@NamedQueries({
@NamedQuery(name=DeliveryType.DISPLAYABLE,
query="select s from DeliveryType s where s.isDisplayable = 'Y'" ),
@NamedQuery(name=DeliveryType.DUPE_CHECK,
query="select s from DeliveryType s where lower(s.description)=lower(:description)" )
})
public class DeliveryType implements Serializable, Comparable<DeliveryType> {
}
Is it possible that rather than swapping out which DeliveryType object is associated with a Journal, the application, rather is trying to modify the DeliveryType object that is ALREADY associated with the Journal? Even if it was, it should trigger an UPDATE, not an INSERT, right?
Again, thanks for your help!
|
|
| | | | |
Goto Forum:
Current Time: Sat Jul 05 07:18:32 EDT 2025
Powered by FUDForum. Page generated in 0.04542 seconds
|