In addition to [all][1] [the][2] [other][3] excellent answers...

# Seeking new employment

    @Override
    public void fire() {
        this.salary = 0;
        this.employer = HOMELESS;
        isHappy = false;
        status = LOOKING_FOR_NEW_JOB;
    }

I'm pretty sure `HOMLESS` can't be an employer. Also, does calling this method imply the engineer is fired, or the engineer has decided to fire the employer? Should there be a difference between `resign()` and `retrench()`?

# Dates

Using `long` primitive to represent 'times' is an archaic concept from the old `java.util.Date`-based classes. In case you are not on Java 8 (with its new `java.time.*` APIs), you should look at the [JodaTime][4] library to better represent chronological events/periods. The `long` primitive also makes it questionable what is the [epoch][5] you are using. As a last resort, even a `Date` object will be better as it clearly represents a date-time, and uses the well-understood [Unix epoch][6] so that there is no ambiguity there.

# `equals(Object)` comparison

    @Override
    public boolean equals(Object engineer) {
        if (this == engineer) {
            return true;
        }
        Engineer e = (Engineer) engineer;
        return this.isHappy == e.isHappy() && hashCode() == e.hashCode();
    }

You will also need to `return false` when the input is not an `Engineer` implementation. This is partly why for the `equals(Object)` method, the argument name used here is usually something along the lines of `object`, `obj`, `other` or just `o`. It *cannot be assumed* that the casting will always work.

[1]: http://codereview.stackexchange.com/a/107638/24141
[2]: http://codereview.stackexchange.com/a/107648/24141
[3]: http://codereview.stackexchange.com/a/107695/24141
[4]: http://www.joda.org/joda-time/
[5]: https://en.m.wikipedia.org/wiki/Epoch_(reference_date)
[6]: https://en.m.wikipedia.org/wiki/Unix_epoch