Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Zombie Entities? Constraint violation when modifying removed Entity
Zombie Entities? Constraint violation when modifying removed Entity [message #1818530] Wed, 18 December 2019 20:03 Go to next message
Uwe Pachler is currently offline Uwe PachlerFriend
Messages: 1
Registered: December 2019
Junior Member
Hi all,

I'm encountering quite a weird issue with code that modifies an entity after it was removed (EntityManager.remove()) - and I know the suggested fix will be 'don't do it', but unfortunately things are not that simple, so that's not really a solution for me.

But first things fist, this is what I'm doing:
* I have entityies Employee and Company. A company can have many employees (bidirectional one-to-many). The employee MUST have a company (NOT NULL constraint). In my test code, the tables are generated by EclipseLink, so it itself thinks generating that NOT NULL constraint is the correct thing to do.
* I create a company and an employee, and associate them (both sides updated correctly)
* (0) I persist them and flush them to the database
* (1) I remove the employee (so it is REMOVED)
* (2) then I set company to NULL on the employee (IMHO this shouldn't do anything, but in fact later triggers an UPDATE, which causes trouble) (2)
* (3) Calling em.flush() at the end causes the changes to be written to the database. However, before the Eclipselink tries to DELETE our employe, it performs an UPDATE on it, attempting to set company_id to NULL - which breaks the test, since company_id is NOT NULL constrained.

Now I know changing removed entities may not be the smartest thing to do, however, there are reasons why this may happen anyways (which I think are beyond scope for now).

I'm wondering if I'm doing something even more stupid than modifying the entity after removing it, or if this is an EclipseLink feature, or worse, a bug...

Cheers,

Uwe

P.S.: Tested with EclipseLink 2.7.5.

---- TEST CODE ----

// NOTE: we inherit 'EntityManager em' from outside the test code

@Test
public void test() {
// I create a company with one employee and associate them...
Employee e = Employee.builder()
.firstname("John")
.surname("Doe")
.build();

Company c = Company.builder()
.name("Acme")
.build();
e.setCompany(c);
c.getEmployee().add(e);

em.persist(e);
em.persist(c);

// (0) make sure objects are in the database
em.flush();

// (1) I remove (DELETE) the employee
em.remove(e);

// (2) I change the association on the removed entity
e.setCompany(null);

// (3) The call to flush fails, complaining about a failed
// NOT NULL contstraint
em.flush();

}

---- OUTPUT ----

javax.persistence.PersistenceException:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.1.v20171221-bd47e8f): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10099 table: EMPLOYEE column: COMPANY_ID
Error Code: -10
Call: UPDATE EMPLOYEE SET COMPANY_ID = ? WHERE (ID = ?)
bind => [null, 1]
Query: UpdateObjectQuery(com.github.gentity.test.test1a_many_to_one.Employee@7ae0a9ec)
at com.github.gentity.test.Test1a_many_to_one.test(Test1a_many_to_one.java:59)
Caused by: org.eclipse.persistence.exceptions.DatabaseException:

Internal Exception: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10099 table: EMPLOYEE column: COMPANY_ID
Error Code: -10
Call: UPDATE EMPLOYEE SET COMPANY_ID = ? WHERE (ID = ?)
bind => [null, 1]
Query: UpdateObjectQuery(com.github.gentity.test.test1a_many_to_one.Employee@7ae0a9ec)
at com.github.gentity.test.Test1a_many_to_one.test(Test1a_many_to_one.java:59)
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10099 table: EMPLOYEE column: COMPANY_ID
at com.github.gentity.test.Test1a_many_to_one.test(Test1a_many_to_one.java:59)
Caused by: org.hsqldb.HsqlException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10099 table: EMPLOYEE column: COMPANY_ID
at com.github.gentity.test.Test1a_many_to_one.test(Test1a_many_to_one.java:59)



---- ENTITIES ----

@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected Long id;
@Column(name = "FIRSTNAME", length = 100)
protected String firstname;
@Column(name = "SURNAME", length = 100)
protected String surname;
@ManyToOne
@JoinColumn(name = "COMPANY_ID", nullable = false)
protected Company company;
//... methods omitted
}

@Entity
@Table(name = "COMPANY")
public class Company implements Serializable
{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected Long id;
@Column(name = "NAME", length = 100, nullable = false)
protected String name;
@OneToMany(mappedBy = "company")
protected List<Employee> employee = new ArrayList();
//... methods omitted
}

Re: Zombie Entities? Constraint violation when modifying removed Entity [message #1818971 is a reply to message #1818530] Fri, 03 January 2020 18:54 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1339
Registered: July 2009
Senior Member
If you made the change to set null on the relationship before the remove call, would you expect the update statement to have occurred?
You already know - don't do it, as your changes put the entity in an invalid state so shouldn't be being done.
Why: It is doing what you told it to do - updating the entity. You have called a bunch of actions in the persistence unit. That you called remove on an entity hasn't actually removed it from the persistence unit - it is still a managed instance and EclipseLink is still required to track the changes you make to it, and having to modify rows before being able to delete them is a common requirement should you have had a cascade on delete foreign key and didn't want the referenced row to get cleared.

Tom discusses it a bit here: https://www.eclipse.org/lists/eclipselink-users/msg05763.html
Previous Topic:npe while unmarshal date field as json array
Next Topic:Multitenant per table and native query
Goto Forum:
  


Current Time: Thu Feb 20 04:54:35 GMT 2020

Powered by FUDForum. Page generated in 0.05454 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top