/******************************************************************************* | |
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved. | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* 07/16/2009 Andrei Ilitchev | |
* - Bug 282553: JPA 2.0 JoinTable support for OneToOne and ManyToOne | |
******************************************************************************/ | |
package org.eclipse.persistence.testing.models.onetoonejointable; | |
import java.util.*; | |
import java.io.*; | |
import java.math.BigDecimal; | |
import java.beans.PropertyChangeListener; | |
import java.beans.PropertyChangeEvent; | |
import org.eclipse.persistence.indirection.*; | |
import org.eclipse.persistence.descriptors.changetracking.*; | |
/** | |
* <p><b>Purpose</b>: Represent a employee of an organization. | |
* <p><b>Description</b>: An Employee is a root object in the Employee Demo. | |
* It maintains relationships to all of the other objects in the system. | |
* The employee shows usage of 1-1, 1-m, m-m, aggregate and transformation mappings. | |
* The employee also shows usage of value holder to implement indirection for its relationships | |
* (note, it is strongly suggested to always use value holders for relationships). | |
*/ | |
public class Employee implements Serializable, ChangeTracker { | |
// implements ChangeTracker for testing | |
/** Primary key, mapped as a direct-to-field, BigDecimal -> NUMBER, that makes use of sequence numbers to generate the id. */ | |
public BigDecimal id; | |
/** Direct-to-field mapping, String -> VARCHAR. */ | |
public String firstName; | |
/** Direct-to-field mapping, String -> VARCHAR. */ | |
public String lastName; | |
/** Object-type mapping, maps "Male" -> "M", "Female" -> "F". */ | |
public String gender; | |
/** One-to-one mapping, employee references its address through a foreign key. */ | |
public ValueHolderInterface address; | |
/** One-to-one mapping (same class relationship), employee references its manager through a foreign key. */ | |
public ValueHolderInterface manager; | |
public List<Employee> managedEmployees; | |
/** Many-to-many mapping, employee references its projects through an intermediate join table. */ | |
public List<Project> projects; | |
/** Direct-collection mapping, employee stores its collection of plain Strings in an intermediate table. */ | |
public List<String> responsibilitiesList; | |
/** Direct-to-field mapping, int -> NUMBER, salary of the employee in dollars. */ | |
public int salary; | |
/** One-to-many mapping, employee references its collection of children arranged by age. | |
* This relationship uses transparent indirection */ | |
public List<Child> children; | |
/** One-to-one mapping , inverse relationship to Project.teamLeader */ | |
public ValueHolderInterface projectLed; | |
/** For performance testing, how many times primary key extracted. */ | |
public static int getIdCallCount = 0; | |
public PropertyChangeListener listener; | |
public PropertyChangeListener _persistence_getPropertyChangeListener() { | |
return listener; | |
} | |
public void _persistence_setPropertyChangeListener(PropertyChangeListener listener) { | |
this.listener = listener; | |
} | |
public void propertyChange(String propertyName, Object oldValue, Object newValue) { | |
if (listener != null) { | |
if (oldValue != newValue) { | |
listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue)); | |
} | |
} | |
} | |
public void collectionChange(String propertyName, Object oldValue, Object newValue, int changeType, boolean isChangeApplied) { | |
if (listener != null) { | |
listener.propertyChange(new CollectionChangeEvent(this, propertyName, oldValue, newValue, changeType, isChangeApplied)); | |
} | |
} | |
/** | |
* For fields that make use of indirection the constructor should build the value holders. | |
*/ | |
public Employee() { | |
this.firstName = ""; | |
this.lastName = ""; | |
this.address = new ValueHolder(); | |
this.manager = new ValueHolder(); | |
this.managedEmployees = new ArrayList(); | |
this.projects = new ArrayList(); | |
this.responsibilitiesList = new ArrayList(); | |
this.children = new ArrayList(); | |
this.projectLed = new ValueHolder(); | |
} | |
/** | |
* For bi-directional relationships, it is important to maintain both sides of the relationship when changing it. | |
*/ | |
public void addManagedEmployee(Employee employee) { | |
getManagedEmployees().add(employee); | |
employee.setManager(this); | |
} | |
public void addManagedEmployee(int index, Employee employee) { | |
getManagedEmployees().add(index, employee); | |
employee.setManager(this); | |
} | |
public Employee setManagedEmployee(int index, Employee employee) { | |
Employee removedEmp = getManagedEmployees().set(index, employee); | |
removedEmp.setManager(null); | |
employee.setManager(this); | |
return removedEmp; | |
} | |
public void addChild(Child child) { | |
getChildren().add(child); | |
child.setParent(this); | |
} | |
public void addProject(Project project) { | |
getProjects().add(project); | |
project.getEmployees().add(this); | |
} | |
public void addResponsibility(String responsibility) { | |
getResponsibilitiesList().add(responsibility); | |
} | |
public Address getAddress() { | |
return (Address)address.getValue(); | |
} | |
public String getFirstName() { | |
return firstName; | |
} | |
public String getGender() { | |
return gender; | |
} | |
/** | |
* Used for performance testing. | |
*/ | |
public static int getGetIdCallCount() { | |
return getIdCallCount; | |
} | |
/** | |
* Return the persistent identifier of the receiver. | |
*/ | |
public BigDecimal getId() { | |
getIdCallCount++; | |
return id; | |
} | |
public List<Child> getChildren(){ | |
return children; | |
} | |
public String getLastName() { | |
return lastName; | |
} | |
public List<Employee> getManagedEmployees() { | |
return managedEmployees; | |
} | |
public Employee getManager() { | |
return (Employee)manager.getValue(); | |
} | |
public Project getProjectLed() { | |
return (Project)projectLed.getValue(); | |
} | |
public List<Project> getProjects() { | |
return projects; | |
} | |
public List<String> getResponsibilitiesList() { | |
return responsibilitiesList; | |
} | |
public int getSalary() { | |
return salary; | |
} | |
public void removeManagedEmployee(Employee employee) { | |
getManagedEmployees().remove(employee); | |
employee.setManager(null); | |
} | |
public void removeProject(Project project) { | |
getProjects().remove(project); | |
project.getEmployees().remove(this); | |
} | |
public void removeResponsibility(String responsibility) { | |
getResponsibilitiesList().remove(responsibility); | |
} | |
public void setAddress(Address address) { | |
propertyChange("address", this.address.getValue(), address); | |
this.address.setValue(address); | |
} | |
public void setChildren(Vector children){ | |
this.children = children; | |
} | |
public void setFemale() { | |
propertyChange("gender", this.gender, "Female"); | |
setGender("Female"); | |
} | |
public void setFirstName(String firstName) { | |
propertyChange("firstName", getFirstName(), firstName); | |
this.firstName = firstName; | |
} | |
public void setGender(String gender) { | |
propertyChange("gender", this.gender, gender); | |
this.gender = gender; | |
} | |
/** | |
* For performance testing. | |
*/ | |
public static void setGetIdCallCount(int value) { | |
Employee.getIdCallCount = value; | |
} | |
/** | |
* Set the persistent identifier of the receiver. | |
* Note this should never be changed. | |
* Consider making the primary key set methods protected or not having them. | |
* In this demo the setId is required for testing purposes. | |
*/ | |
public void setId(BigDecimal id) { | |
propertyChange("id", this.id, id); | |
this.id = id; | |
} | |
public void setLastName(String lastName) { | |
propertyChange("lastName", this.lastName, lastName); | |
this.lastName = lastName; | |
} | |
public void setMale() { | |
propertyChange("gender", this.gender, "Male"); | |
setGender("Male"); | |
} | |
/** | |
* Notice that the usage of value holders does not effect the public interface or usage of the class. | |
* The get/set methods must however be changed to wrap/unwrap the value holder. | |
*/ | |
public void setManagedEmployees(List<Employee> managedEmployees) { | |
propertyChange("managedEmployees", this.managedEmployees, managedEmployees); | |
this.managedEmployees = managedEmployees; | |
} | |
/** | |
* For bi-directional relationships, it is important to maintain both sides of the relationship when changing it. | |
* Notice that the usage of value holders does not effect the public interface or usage of the class. | |
* The get/set methods must however be changed to wrap/unwrap the value holder. | |
*/ | |
public void setManager(Employee manager) { | |
propertyChange("manager", this.manager.getValue(), manager); | |
this.manager.setValue(manager); | |
} | |
public void setProjectLed(Project projectLed) { | |
propertyChange("projectLed", this.projectLed.getValue(), projectLed); | |
this.projectLed.setValue(projectLed); | |
} | |
public void setProjects(List<Project> projects) { | |
propertyChange("projects", this.projects, projects); | |
this.projects = projects; | |
} | |
/** | |
* Notice that the usage of value holders does not effect the public interface or usage of the class. | |
* The get/set methods must however be changed to wrap/unwrap the value holder. | |
*/ | |
public void setResponsibilitiesList(Vector responsibilitiesList) { | |
propertyChange("responsibilitiesList", this.responsibilitiesList, responsibilitiesList); | |
this.responsibilitiesList = responsibilitiesList; | |
} | |
public void setSalary(int salary) { | |
propertyChange("salary", new Integer(this.salary), new Integer(salary)); | |
this.salary = salary; | |
} | |
/** | |
* Print the first & last name | |
*/ | |
public String toString() { | |
StringWriter writer = new StringWriter(); | |
writer.write("Employee: "); | |
writer.write(getFirstName()); | |
writer.write(" "); | |
writer.write(getLastName()); | |
return writer.toString(); | |
} | |
} |