I have an Entity like this:
Code:
@Entity
@Table(name = "VIOLATION")
public final class Violation {
@ManyToOne
@ForeignKey(name = "FK_VIOLATION_TRANSACTION")
@JoinColumn(name = "TRANSACTION_ID")
private Transaction transaction;
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.EAGER)
@ForeignKey(name = "FK_VIOLATION_OBJECT_REF", inverseName = "FK_OBJECT_REF_VIOLATION")
@JoinColumn(name = "OBJECT_REF_ID")
private ObjectRef objectRef;
}
Let's say I already have an ObjectRef persisted in the database in OBJECT_REF table like this row:
Code:
| ID | GEOM | REF_NAME | REF_ID |
| 1 | MDSYS.SDO_GEOM | ref name 1 | 1000001 |
Now, if create a new Violation object, like this:
Code:
// same as row in database
ObjectRef oRef = new ObjectRef("ref name", 1000001, new Geometry());
Violation v = new Violation("some text", oRef);
Transaction t; // already have instance of transaction
t.addViolation(v);
em.persist(v);
This triggers a unique constraint violation for me, since on ObjectRef entity I have this:
Code:
@Entity
@Table(name = "OBJECT_REF", uniqueConstraints = { @UniqueConstraint(columnNames = { "REF_NAME", "REF_ID" }) })
public final class ObjectRef {
So, I wrote some code instead, that does a Query to find if an ObjectRef entity is already persisted...if so, I override the detached instance that was set in the constructor...
Code:
Query q = getEntityManager().createQuery("from ObjectRef where name = :name and refId = :refId")
.setParameter("name", v.getObjectRef().getRefName())
.setParameter("refId", v.getObjectRef().getRefId());
ObjectRef oRef = (ObjectRef) q.getSingleResult();
if(oRef != null) { v.setObejctRef(oRef); }
em.persist(v);
This works, but I hit another problem. When the query is issued, all outstanding operations are flushed...and the Transaction entity now tries to get persisted, which cascades persisting the Violation, and then the ObjectRef -- which again hits my unique constraint violation.
I can get around this by do em.clear() to clear the cache, then finding the ObjectRef, setting it, persisting it, and then manually setting link again between the Transaction and the Violation, but this all seems so wrong...I feel like there must be a much easier and correct way to do this.
Can anyone offer some insight?
Thanks in advance,
Davis