/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2;

import java.sql.Time;
import java.util.*;
import java.io.Serializable;
import jakarta.persistence.*;

import org.eclipse.persistence.annotations.Cache;
import org.eclipse.persistence.annotations.ChangeTracking;
import org.eclipse.persistence.annotations.CompositeMember;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Customizer;
import org.eclipse.persistence.annotations.ExistenceChecking;
import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.annotations.JoinFetch;
import org.eclipse.persistence.annotations.JoinFetchType;
import org.eclipse.persistence.annotations.Mutable;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
import org.eclipse.persistence.annotations.OptimisticLocking;
import org.eclipse.persistence.annotations.PrimaryKey;
import org.eclipse.persistence.annotations.PrivateOwned;
import org.eclipse.persistence.annotations.Property;
import org.eclipse.persistence.annotations.Properties;
import org.eclipse.persistence.annotations.ReadTransformer;
import org.eclipse.persistence.annotations.TypeConverter;
import org.eclipse.persistence.annotations.WriteTransformer;
import org.eclipse.persistence.annotations.WriteTransformers;
import org.eclipse.persistence.config.CacheIsolationType;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Address;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Department;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.Dealer;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.HugeProject;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.Project;

import static jakarta.persistence.CascadeType.*;
import static jakarta.persistence.FetchType.*;
import static jakarta.persistence.GenerationType.*;

import static org.eclipse.persistence.annotations.CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS;
import static org.eclipse.persistence.annotations.CacheType.SOFT_WEAK;
import static org.eclipse.persistence.annotations.ChangeTrackingType.AUTO;
import static org.eclipse.persistence.annotations.ExistenceType.CHECK_DATABASE;
import static org.eclipse.persistence.annotations.OptimisticLockingType.VERSION_COLUMN;

/**
 * Employees have a one-to-many relationship with Employees through the
 * managedEmployees attribute.
 * Addresses exist in one-to-one relationships with Employees through the
 * address attribute.
 * Employees have a many-to-many relationship with Projects through the
 * projects attribute.
 *
 * Employee now has invalid annotation fields and data. This is done so that
 * we may test the XML/Annotation merging. Employee has been defined in the
 * XML, therefore, most annotations should not be processed. If they are, then
 * they will force an error, which means something is wrong with our merging.
 *
 * The invalid annotations that should not be processed have _INVALID
 * appended to some annotation field member. Others will not have this,
 * which means they should be processed (their mappings are not defined in the
 * XML)
 */
@SuppressWarnings("deprecation")
@Entity
@EntityListeners(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.EmployeeListener.class)
@Table(name="MBR2_EMPLOYEE")
@SecondaryTable(name="MBR2_SALARY")
@PrimaryKeyJoinColumn(name="EMP_ID", referencedColumnName="EMP_ID")
@NamedNativeQuery(
    name="findAllSQLEmployees",
    query="select * from MBR2_EMPLOYEE",
    resultClass=org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.Employee.class
)
@NamedQueries({
@NamedQuery(
    name="findAllEmployeesByFirstName",
    query="SELECT OBJECT(employee) FROM Employee employee WHERE employee.firstName = :firstname"
),
@NamedQuery(
    name="constuctEmployees",
        query="SELECT new org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.Employee(employee.firstName, employee.lastName) FROM Employee employee"
),
@NamedQuery(
    name="findEmployeeByPK",
    query="SELECT OBJECT(employee) FROM Employee employee WHERE employee.id = :id"
),
@NamedQuery(
        name="findEmployeeByPostalCode",
        query="SELECT e FROM Employee e where e.address.postalCode = :postalCode"
),
@NamedQuery(
        name="findAllEmployeesOrderById",
        query="SELECT e FROM Employee e order by e.id"
),
// Cannot join tables in different data bases
/*@NamedQuery(
        name="findAllEmployeesJoinAddressPhones",
        query="SELECT e FROM Employee e",
        hints={
                @QueryHint(name=QueryHints.FETCH, value="e.address"),
                @QueryHint(name=QueryHints.FETCH, value="e.phoneNumbers")
        }
),*/
@NamedQuery(
        name="CachedAllEmployees",
        query="SELECT e FROM Employee e",
        hints={
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_TYPE, value="FULL"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_IGNORE_NULL, value="false"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY, value="true"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value="200"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_EXPIRY, value="50000")
        }
),
@NamedQuery(
        name="CachedNoEmployees",
        query="SELECT e FROM Employee e where 1 <> 1",
        hints={
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true")
        }
),
@NamedQuery(
        name="CachedTimeOfDayAllEmployees",
        query="SELECT e FROM Employee e",
        hints={
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value="200"),
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_EXPIRY_TIME_OF_DAY, value="23:59:59")
        }
),
@NamedQuery(
    name="findAllEmployeesByIdAndFirstName",
    query="Select employee from Employee employee where employee.id = :id and employee.firstName = :firstName",
    hints={
                @QueryHint(name=QueryHints.PESSIMISTIC_LOCK_TIMEOUT, value="15000")
    }
),
// BUG 259329 - Update named queries have a lock mode type defaulted to NONE need to
// internally not only check for null but NONE as well.
@NamedQuery(
        name="UpdateEmployeeQueryWithLockModeNONE",
        query="UPDATE Employee e set e.salary = 100 where e.firstName like 'blah'"
)
}
)
@OptimisticLocking(
    type=VERSION_COLUMN
)
@ObjectTypeConverter(
    name="sex",
    dataType=String.class,
    objectType=org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.Employee.Gender.class,
    conversionValues={
        @ConversionValue(dataValue="F", objectValue="Female"),
        @ConversionValue(dataValue="M", objectValue="Male")
    }
)
@TypeConverter(
    name="Long2String",
    dataType=String.class,
    objectType=Long.class
)
@Cache(
    type=SOFT_WEAK,
    size=730,
    isolation=CacheIsolationType.SHARED,
    expiry=1000000,
    alwaysRefresh=false, // some test dependencies for this to be false.
    disableHits=true, // Employee customizer should set it back to false.
    coordinationType=INVALIDATE_CHANGED_OBJECTS
)
@ChangeTracking(AUTO)
@ExistenceChecking(CHECK_DATABASE)
@Customizer(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.EmployeeCustomizer.class)
@Properties({
    @Property(name="entityName", value="Employee"),
    @Property(name="entityIntegerProperty", value="1", valueType=Integer.class)
}
)
// overrides IdValidation.NEGATIVE set in persistence.xml
@PrimaryKey(validation=IdValidation.ZERO)
public class Employee implements Serializable, Cloneable {
    public enum EmployeeStatus {FULL_TIME, PART_TIME, CONTRACT}
    public enum Gender { Female, Male }
    public enum SalaryRate {
        JUNIOR("JUN"),
        SENIOR("SEN"),
        MANAGER("MAN"),
        EXECUTIVE("EX");

        String salaryRate;
        SalaryRate(String salaryRate){
            this.salaryRate=salaryRate;
        }
        public String toString() {
            return salaryRate;
         }

    }
    public enum Weekdays { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }

    private int salary;
    private int roomNumber;

    private Integer id;
    private Integer version;

    private Gender gender;
    private EmployeeStatus status;
    private SalaryRate payScale;

    /** The field names intentionally do not match the property names to test method weaving. */
    private String m_lastName;
    private String m_firstName;

    /** Transformation mapping, a two(2) element array holding the employee's normal working hours (START_TIME &amp; END_TIME),
    this is stored into two different fields in the employee table. */
    private Time[] normalHours;
    /** Transformation mapping, a two(2) element array holding the employee's overtime hours (OVERTIME_START_TIME &amp; OVERTIME_END_TIME),
    this is stored into two different fields in the employee table. */
    private Time[] overtimeHours;

    private Address m_address;
    private Department department;
    private Employee manager;
    private EmploymentPeriod period;
    private FormerEmployment formerEmployment;
    private Set<Weekdays> workWeek;

    private Collection<Project> projects;
    private Collection<String> responsibilities;
    private Collection<PhoneNumber> m_phoneNumbers;
    private Collection<Employee> managedEmployees;
    private List<Dealer> dealers;

    private HugeProject hugeProject;

    public Employee () {
        this.normalHours = new Time[2];
        this.overtimeHours = new Time[2];
        this.m_phoneNumbers = new Vector<PhoneNumber>();
        this.projects = new Vector<Project>();
        this.managedEmployees = new Vector<Employee>();
        this.responsibilities = new Vector<String>();
        this.dealers = new ArrayList<Dealer>();
    }

    public Employee(String firstName, String lastName){
        this();
        this.m_firstName = firstName;
        this.m_lastName = lastName;
    }

    @Override
    public Employee clone() {
        Employee clone = null;
        try {
            clone = (Employee)super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.toString());
        }
        clone.projects = new Vector(this.projects);
        clone.managedEmployees = new Vector(this.managedEmployees);
        clone.responsibilities = new Vector(this.responsibilities);
        return clone;
    }

    public void addDealer(Dealer dealer) {
        dealers.add(dealer);
    }

    public void addManagedEmployee(Employee emp) {
        getManagedEmployees().add(emp);
        emp.setManager(this);
    }

    public void addPhoneNumber(PhoneNumber phone) {
        phone.setOwner(this);
        getPhoneNumbers().add(phone);
    }

    public void addProject(Project theProject) {
        getProjects().add(theProject);
    }

    public void addResponsibility(String responsibility) {
        getResponsibilities().add(responsibility);
    }

    /**
     * Builds the normalHours Vector.
     * IMPORTANT: This method builds the value but does not set it.
     * The mapping will set it using method or direct access as defined in the descriptor.
     */
    public Time[] buildNormalHours(Record row, Session session) {
        Time[] hours = new Time[2];

        /** This conversion allows for the database type not to match, i.e. may be a Timestamp or String. */
        hours[0] = (Time) session.getDatasourcePlatform().convertObject(row.get("START_TIME"), java.sql.Time.class);
        hours[1] = (Time) session.getDatasourcePlatform().convertObject(row.get("END_TIME"), java.sql.Time.class);
        return hours;
    }

    public String displayString() {
        StringBuffer sbuff = new StringBuffer();
        sbuff.append("Employee ").append(getId()).append(": ").append(getLastName()).append(", ").append(getFirstName()).append(getSalary());

        return sbuff.toString();
    }

    // Testing - Static method should be ignored
    static public void getAbsolutelyNothing() {}

    @ManyToOne(cascade={PERSIST, MERGE}, fetch=LAZY)
    @JoinColumn(name="ADDR_ID")
    @Property(name="attributeName", value="address")
    public Address getAddress() {
        return m_address;
    }

    // Testing - Get methods with no corresponding set method, should be
    // ignored. Logs a warning though.
    public String getAnEmptyString() {
        return "";
    }

    @OneToMany(cascade={PERSIST, MERGE})
    @JoinColumn(name="FK_EMP_ID")
    @Property(name="attributeName", value="dealers")
    public List<Dealer> getDealers() {
        return dealers;
    }

    /**
     * Return the last element of the Transformation mapped overtimeHours.
     */
    @Transient
    public Time getEndOvertime() {
        return getOvertimeHours()[1];
    }

    /**
     * Return the last element of the Transformation mapped normalHours.
     */
    @Transient
    public Time getEndTime() {
        return getNormalHours()[1];
    }

    @ManyToOne(fetch=EAGER)
    @JoinColumn(name="DEPT_ID")
// Can't join with table in another db    @JoinFetch(JoinFetchType.OUTER)
    @Property(name="attributeName", value="department")
    public Department getDepartment() {
        return department;
    }

    @Column(name="F_NAME")
    @Property(name="attributeName", value="firstName")
    public String getFirstName() {
        return m_firstName;
    }

    @Convert("sex")
    @Property(name="attributeName", value="gender")
    public Gender getGender() {
        return gender;
    }

    @Id
    @GeneratedValue(strategy=TABLE, generator="BR2_EMPLOYEE_TABLE_GENERATOR")
    @TableGenerator(
        name="BR2_EMPLOYEE_TABLE_GENERATOR",
        table="MBR2_SEQ",
        pkColumnName="SEQ_NAME",
        valueColumnName="SEQ_COUNT",
        pkColumnValue="EMPLOYEE_SEQ",
        initialValue=50
    )
    @Column(name="EMP_ID", length=21)
    @Property(name="attributeName", value="id")
    public Integer getId() {
        return id;
    }

    // Not defined in the XML, this should get processed.
    @Column(name="L_NAME")
    @Properties({
        @Property(name="attributeName", value="lastName"),
        @Property(name="BooleanProperty", value="true", valueType=Boolean.class),
        @Property(name="ByteProperty", value="1", valueType=Byte.class),
        @Property(name="CharacterProperty", value="A", valueType=Character.class),
        @Property(name="DoubleProperty", value="1", valueType=Double.class),
        @Property(name="FloatProperty", value="1", valueType=Float.class),
        @Property(name="IntegerProperty", value="1", valueType=Integer.class),
        @Property(name="LongProperty", value="1", valueType=Long.class),
        @Property(name="ShortProperty", value="1", valueType=Short.class),
        @Property(name="BigDecimalProperty", value="1", valueType=java.math.BigDecimal.class),
        @Property(name="BigIntegerProperty", value="1", valueType=java.math.BigInteger.class),
        // it's a HEX string therefore it has to have an even number of bytes
        @Property(name="byte[]Property", value="01020304", valueType=byte[].class),
        @Property(name="char[]Property", value="abc", valueType=char[].class),
        @Property(name="Byte[]Property", value="01020304", valueType=Byte[].class),
        @Property(name="Character[]Property", value="abc", valueType=Character[].class),
        @Property(name="TimeProperty", value="13:59:59", valueType=java.sql.Time.class),
        @Property(name="TimeStampProperty", value="2008-04-10 13:59:59", valueType=java.sql.Timestamp.class),
        @Property(name="DateProperty", value="2008-04-10", valueType=java.sql.Date.class)
    })
    public String getLastName() {
        return m_lastName;
    }

    @OneToMany(cascade=ALL, mappedBy="manager")
    @Property(name="attributeName", value="managedEmployees")
    public Collection<Employee> getManagedEmployees() {
        return managedEmployees;
    }

    // Not defined in the XML, this should get processed.
    @ManyToOne(cascade=PERSIST, fetch=LAZY)
    @Property(name="attributeName", value="manager")
    public Employee getManager() {
        return manager;
    }

    @Mutable(false)
    @ReadTransformer(method="buildNormalHours")
    @WriteTransformers({
        @WriteTransformer(method="getStartTime", column=@Column(name="START_TIME")),
        @WriteTransformer(method="getEndTime", column=@Column(name="END_TIME"))
    })
    @Property(name="attributeName", value="normalHours")
    protected Time[] getNormalHours() {
        return normalHours;
    }

    @Mutable(false)
    @ReadTransformer(transformerClass=org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.AdvancedReadTransformer.class)
    @WriteTransformers({
        @WriteTransformer(transformerClass=org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.AdvancedWriteTransformer.class, column=@Column(name="START_OVERTIME", columnDefinition="TIME")),
        @WriteTransformer(transformerClass=org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.AdvancedWriteTransformer.class, column=@Column(name="END_OVERTIME", columnDefinition="TIME"))
    })
    @Property(name="attributeName", value="overtimeHours")
    protected Time[] getOvertimeHours() {
        return overtimeHours;
    }

    @Enumerated(EnumType.STRING)
    @Column(name="PAY_SCALE")
    @Property(name="attributeName", value="payScale")
    public SalaryRate getPayScale() {
        return payScale;
    }

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="startDate", column=@Column(name="START_DATE", nullable=false)),
        @AttributeOverride(name="endDate", column=@Column(name="END_DATE", nullable=true))
    })
    @Property(name="attributeName", value="period")
    public EmploymentPeriod getPeriod() {
        return period;
    }

    @OneToMany(cascade=ALL, mappedBy="owner")
    @PrivateOwned
    @Property(name="attributeName", value="phoneNumbers")
    public Collection<PhoneNumber> getPhoneNumbers() {
        return m_phoneNumbers;
    }

    @ManyToMany(cascade={PERSIST, MERGE})
    @JoinTable(
        name="MBR3_EMP_PROJ",
        // Default for the project side and specify for the employee side
        // Will test both defaulting and set values.
        joinColumns=@JoinColumn(name="EMPLOYEES_EMP_ID", referencedColumnName="EMP_ID")
        //inverseJoinColumns=@JoinColumn(name="PROJECTS_PROJ_ID", referencedColumnName="PROJ_ID")
    )
    @Property(name="attributeName", value="projects")
    public Collection<Project> getProjects() {
        return projects;
    }

    @ElementCollection(targetClass=String.class)
    @CollectionTable(name = "MBR1_RESPONS", joinColumns=@JoinColumn(name="EMP_ID"))
    @CompositeMember("composite-advanced-member_1")
    @Column(name = "DESCRIPTION")
    // generics left off the Collection on purpose ...
    @Property(name="attributeName", value="responsibilities")
    public Collection getResponsibilities() {
        return responsibilities;
    }

    @Column(name="ROOM_NUM")
    @Property(name="attributeName", value="roomNumber")
    public int getRoomNumber() {
        return roomNumber;
    }

    @Column(table="MBR2_SALARY")
    @Property(name="attributeName", value="salary")
    public int getSalary() {
        return salary;
    }

    /**
     * Return the first element of the Transformation mapped overtimeHours.
     */
    @Transient
    public java.sql.Time getStartOvertime() {
        return getOvertimeHours()[0];
    }

    /**
     * Return the first element of the Transformation mapped normalHours.
     */
    @Transient
    public java.sql.Time getStartTime() {
        return getNormalHours()[0];
    }

    @Enumerated
    @Column(name="STATUS")
    @Property(name="attributeName", value="status")
    public EmployeeStatus getStatus() {
        return status;
    }

    @Version
    @Column(name="VERSION")
    @Property(name="attributeName", value="version")
    public Integer getVersion() {
        return version;
    }

    @ElementCollection
    @CollectionTable(name="MBR1_WORKWEEK", joinColumns=@JoinColumn(name="EMP_ID"))
    @CompositeMember("composite-advanced-member_1")
    @Column(name="WORKWEEK")
    @Property(name="attributeName", value="workWeek")
    public Set<Weekdays> getWorkWeek() {
        return workWeek;
    }

    // Testing - Get methods with parameters should be ignored
    public String getYourStringBack(String str) {
        return str;
    }

    public boolean isFemale() {
        return gender.equals(Gender.Female);
    }

    public boolean isMale() {
        return gender.equals(Gender.Male);
    }

    public void removeDealer(Dealer dealer) {
        dealers.remove(dealer);
    }

    public void removeManagedEmployee(Employee emp) {
        getManagedEmployees().remove(emp);
    }

    public void removePhoneNumber(PhoneNumber phone) {
        // Note that getPhoneNumbers() will not have a phone number identical to
        // "phone", (because it's serialized) and this will take advantage of
        // equals() in PhoneNumber to remove properly
        getPhoneNumbers().remove(phone);
    }

    public void removeProject(Project theProject) {
        getProjects().remove(theProject);
    }

    public void removeResponsibility(String responsibility) {
        getResponsibilities().remove(responsibility);
    }

    public void setAddress(Address address) {
        this.m_address = address;
    }

    /**
     * This tests having multiple getAddress methods, to ensure the weaver doesn't get confused.
     */
    public Address getAddress(String type) {
        if (type.equals("Home")) {
            return getAddress();
        } else return new Address();
    }

    /**
     * This tests having multiple setAddress methods, to ensure the weaver doesn't get confused.
     */
    public void setAddress(String city) {
        getAddress().setCity(city);
    }

    public void setAddressField(Address address){
        // Set the field directly to test if the change is still detected.
        this.m_address = address;
    }

    public void setDealers(List<Dealer> dealers) {
        this.dealers = dealers;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    /**
     * Set the last element of the Transformation mapped overtimeHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setEndOvertime(Time endOvertime) {
        Time[] newOvertimeHours = new Time[] {getStartOvertime(), endOvertime};
        setOvertimeHours(newOvertimeHours);
    }

    /**
     * Set the last element of the Transformation mapped normalHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setEndTime(Time endTime) {
        Time[] newNormalHours = new Time[] {getStartTime(), endTime};
        setNormalHours(newNormalHours);
    }

    public void setFemale() {
        this.gender = Gender.Female;
    }

    public void setFirstName(String name) {
        this.m_firstName = name;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setLastName(String name) {
        this.m_lastName = name;
    }

    public void setMale() {
        this.gender = Gender.Male;
    }

    public void setManagedEmployees(Collection<Employee> managedEmployees) {
        this.managedEmployees = managedEmployees;
    }

    public void setManagerField(Employee manager) {
        this.manager = manager;
    }

    public void setManager(Employee manager) {
        this.manager = manager;
    }

    public void setMondayToFridayWorkWeek() {
        setWorkWeek(EnumSet.of(Weekdays.MONDAY, Weekdays.FRIDAY));
    }

    public void setNormalHours(Time[] normalHours) {
        this.normalHours = normalHours;
    }

    public void setOvertimeHours(Time[] overtimeHours) {
        this.overtimeHours = overtimeHours;
    }

    public void setPayScale(SalaryRate payScale) {
        this.payScale = payScale;
    }

    public void setPeriod(EmploymentPeriod period) {
        this.period = period;
    }

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="formerCompany", column=@Column(name="FORMER_COMPANY", nullable=false)),
        @AttributeOverride(name="startDate", column=@Column(name="FORMER_START_DATE", nullable=false)),
        @AttributeOverride(name="endDate", column=@Column(name="FORMER_END_DATE", nullable=true))
    })
    @Property(name="attributeName", value="formerEmployment")
    public FormerEmployment getFormerEmployment() {
            return formerEmployment;
    }

    public void setFormerEmployment(FormerEmployment formerEmployment) {
            this.formerEmployment = formerEmployment;
    }


    public void setPhoneNumbers(Collection<PhoneNumber> phoneNumbers) {
        this.m_phoneNumbers = phoneNumbers;
    }

    public void setProjects(Collection<Project> projects) {
        this.projects = projects;
    }

    public void setResponsibilities(Collection<String> responsibilities) {
        this.responsibilities = responsibilities;
    }

    public void setRoomNumber(int roomNumber) {
        this.roomNumber = roomNumber;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    /**
     * Set the first element of the Transformation mapped overtimeHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setStartOvertime(Time startOvertime) {
        Time[] newOvertimeHours = new Time[] {startOvertime, getEndOvertime()};
        setOvertimeHours(newOvertimeHours);
    }

    /**
     * Set the first element of the Transformation mapped normalHours.
     * In order to have change tracking, the transformation mapping is not mutable,
     * therefore the whole new array should be created in case either element is changed.
     */
    public void setStartTime(Time startTime) {
        Time[] newNormalHours = new Time[] {startTime, getEndTime()};
        setNormalHours(newNormalHours);
    }

    public void setStatus(EmployeeStatus status) {
        this.status = status;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setWorkWeek(Set<Weekdays> workWeek) {
        this.workWeek = workWeek;
    }

    public String toString() {
        return "Employee: " + getId();
    }

    public boolean worksMondayToFriday() {
        if (getWorkWeek() == null) {
            return false;
        } else {
            return getWorkWeek().equals(EnumSet.of(Weekdays.MONDAY, Weekdays.FRIDAY));
        }
    }

    @OneToOne(fetch=LAZY)
    @JoinColumn(name="HUGE_PROJ_ID")
    @Property(name="attributeName", value="hugeProject")
    public HugeProject getHugeProject() {
        return this.hugeProject;
    }

    public void setHugeProject(HugeProject hugeProject) {
        this.hugeProject = hugeProject;
    }
}
