Account activation email design (with Hibernate in mind)

I have a design problem that I would like information on. Here are the limitations:

  • Each user must have a work email address when registering their account. When registering a user account, you must send an activation email containing a link with an activation code to be followed for the account being activated.
  • Each user account exists in only one office, which only exists in one company.
  • The first registered user from a company creates a company and one office. Then the rest of the company users are invited by the first user.
  • Companies can interact with each other, but only if the first users of the companies are activated (i.e. after registration they have activated their respective activation links).

Here is a small UML diagram of how this can be solved:

alt text http://i43.tinypic.com/2dj5bhh.png

In the above diagram, some details are left out. The diagram shows only classes and fields. When it comes to fields, they are just used conceptually to show what information should be stored, please ignore their scope.

Some thoughts and questions:

  • User and NotActivatedUser are basically the same. Should they be one class or separate? If they are seperated, what form of persistence of Hibernate inheritance would you use?
  • If the account is not activated after a certain time, it should be deleted. If this was the first user to also create Company and Office users, both of these should also be removed. Do we need NotActivatedOffice and NotActivatedCompany? (For clean separation in the database.)

How would you design such a solution? Do you think it is important to keep inactive and active objects separate in the database? Why or why not?

0


source to share


4 answers


I would not use inheritance to represent the state (activated / deactivated) of your User objects. The composition (aggregation) is much better here.

Using aggregation, AbstractUser simply becomes a user. You might want to simulate activation with a class instead of polluting the User class with activation related attributes. This way you get a nice and clean object model.

At the database level, you can still decide to store the two objects in a single table / record called Component Mapping . Or you can decide to keep User and Activation in separate tables (aka Entity Mapping ).

Hibernate supports both types of mappings, mostly a matter of configuration.

The User class will contain the following attributes:

  • GivenName
  • Surname
  • Email
  • (link to activation object)

The activation class will contain the following attributes:



  • activationCode (string)
  • sentOn (when the email was sent)
  • activateOn (default is null, set to the current date / time when the user clicks on the activation link, tells the system if the user has activated their account, if not null)

You can use an HQL query to find out which company has at least one activated user:

from Office o 
   left join fetch o.company 
where 
   o.administrator.activatedOn != null

      

This request assumes that you have defined the "administrator" attribute on your Office class. "Administrator" will be the link to the user who created Office. In the database, the "offices" table has a foreign key for the user record.

By modeling the relationship in this way, you can change the Office administrator (for example, he left or left the office / company). It all depends on your use cases ...

I also added a sentOn attribute to the Activation class used to clear an inactivated account after a certain time (was missing in your UML diagram).

+1


source


I will not separate NotActivatedUser from ActivatedUser; just enter the user table and enter the column "Activated", default 0 (not activated).

One thing; I would split the activation code into a separate table, perhaps using "ActivationMethod". This allows for future extensibility if you want the user to be able to activate their account other than email, and also serves to remove the "activationCode" column from the "User" table.



I am not worried about unactivated offices and companies; according to your use plans as described above, they should not be used by anyone else until that user activates himself (and therefore the office and company). One question; why are you allowing inactive user to create Office and company? Why not limit this activity to activated users only?

0


source


Personally, I would not write two classes for activated and inactive users, because this is just a state. If this state before activation becomes complex, you can refer to the activation state or the like.

If the user has the "OfficeOwner" flag, you know when to delete an office without any complicated logic.

0


source


Using the same table for activated and inactive users requires checking the status of the user as well as offices and companies throughout the application.

For this reason, I would probably use the activrequest table with all the information needed to create a user, ant company office upon activation.

0


source







All Articles