views:

62

answers:

5

Scenario: The "Invoice" has a reference to the class "User". A user object is delete through the user himself or an administrator, but the invoice object still needs a recepient (the user).

The user object could be marked as deleted instead of delete it physically. But I think it is a bad design to use an object, that is marked as deleted. In my opinion objects should only be archived for legal requirements after deletion but not used regularly.

To remove them physically makes some things easier: cascading deletes, selects, database backups ...

How can I avoid using objects marked as deleted? What design do I need to be able to remove unused objects physically from the database? Are there best-practises?

Context: OOP (DDD) application based on Java EE and a relational database.

A: 

At the database level you have at least two solid alternatives.

1) You don't allow a user to be deleted if associated invoices exist.

2) When a user is deleted, all associated invoices are deleted with the user. This can most efficiently be done via Referential Integrity and cascading deletes.

I agree with you that simply marking the invoice as deleted is bad practice. If it's truly been deleted, it should come out of the database (or perhaps archived somewhere).

Randy

Randy Minder
Ok, at the database level I agree with you. But the problem is more at the application / architecture level. On the one hand the user should be deleted, and on the other hand the user data is still needed for the invoice. With referential integrity it wouldn't be possible to delete the user. I need some form of "copy essential data before delete".
deamon
You have a design problem here. If you need to keep the invoice then you need to keep the user. It's really that simple. It would be better to simply mark the user as inactive or something like that. You cannot delete a parent row and leave children rows orphaned. What's the point of keeping the invoice if you don't know who the customer (user) was?
Randy Minder
A: 

Not sure if you need to keep the invoice?

if yes, than you have several options. One is to keep the user with deleted flag. If you are fine with not knowing who the original user was, than create a "Deleted User"-user object. You can link your invoice to that deleted user.

If the answer is no, than just delete all objects that reference to the deleted user. You can do that manually or by using the cascading delete function of the database.

Peter Schuetze
+2  A: 

I have had this discussion a number of times with a number of different people at my organization. I don't think user accounts should ever be deleted. If only for the basic case of being able to easily maintain a record of what the user did. I suggest having a status for users, like active, on_hold, deactivated. Then all you need to to is to deactivate a user account as needed. Of course, when "selecting" a user, you need to verify they are active. This also makes it easier if a user comes back to an organization.

Jay
Agreed - especially in the case of tracking financial transactions. If for some reason you really must delete a user - it would be better to then just anonymize but keep the rest of the relationships and a few fields intact (user type, maybe state, etc).
KenFar
+2  A: 

Is this your real world scenario with invoice and user meaning what I think they mean?

Because, I fail to see how an invoice can ever be deleted in the real world. If an invoice is issued to a customer in error, it could be voided, but the physical data cannot be deleted, otherwise you have no way to retain the information which comprises the invoice. If an invoice is valid but a user associated with it is terminated, you still need to be able to see the user associated with the invoice, otherwise you lose the information about who issued or approved the invoice or whatever.

As far as avoiding using objects who are deleted, I don't think it applies here, because none of these objects CAN actually be deleted. They obviously have an expired, voided, terminated or invalid status for a user creating new invoices or invoices being paid or collected on, but they certainly aren't deleted in the sense of not existing or being considered to not ever having existed, because they obviously did exist at some point since transactions were committed.

Cade Roux
A: 

Why do you need to keep the deleted information? Typically you need to keep it for auditing, compliance, or legal requirements.

Usually, it is sufficient to be able to reproduce earlier states of the database. The database will support this.

For most purposes, it is important to

  1. Log each delete operation
  2. Be able to track when an entry was deleted, and by whom.

If you really aren't allowed to delete it from the database, you can always put it in an archival table, or partition the database table so that the deleted objects don't affect the efficiency of queries.

Larry Watanabe