blob: 721243d091944d4e4d138e180532e8fe4456cd8b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package relations;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
/**
* An entity that contains relations corresponding to family tree relations.
* This entity demonstrates the following JPA features:
*
* 1. Enum fields (gender)
* 2. @OneToOne relations
* 3. @OneToMany relations
* 4. Named queries
*/
@Entity
@NamedQueries({
// a sibling shares a mother and a father
@NamedQuery(name="siblings", query="select distinct sibling1 "
+ "from Deity sibling1, Deity sibling2 where "
+ "sibling1.father = sibling2.father "
+ "and sibling1.mother = sibling2.mother "
+ "and sibling2 = ?1 and sibling1 <> ?1"),
// a half-siling shares a mother or a father, but not both
@NamedQuery(name="half-siblings", query="select distinct sibling1 "
+ "from Deity sibling1, Deity sibling2 where "
+ "((sibling1.father = sibling2.father "
+ "and sibling1.mother <> sibling2.mother) "
+ "or (sibling1.father <> sibling2.father "
+ "and sibling1.mother = sibling2.mother)) "
+ "and sibling2 = ?1 and sibling1 <> ?1"),
// a cousin shares a grandparent, but is not a sibling
@NamedQuery(name="cousins", query="select distinct cousin1 "
+ "from Deity cousin1, Deity cousin2 where "
+ "("
+ "cousin1.father.father = cousin2.father.father "
+ "or cousin1.father.mother = cousin2.father.mother "
+ "or cousin1.mother.father = cousin2.mother.father "
+ "or cousin1.mother.mother = cousin2.mother.mother) "
+ "and (cousin1.father <> cousin2.father) "
+ "and (cousin1.mother <> cousin2.mother) "
+ "and cousin2 = ?1 and cousin1 <> ?1")
})
public class Deity implements Serializable {
private static final long serialVersionUID = 1L;
// the Id is the name, which is generally a bad idea, but we are
// confident that diety names will be unique
@Id
private String name;
@Basic @Enumerated(EnumType.STRING)
private Gender gender;
@OneToOne(cascade=CascadeType.ALL)
private Deity mother;
@OneToOne(cascade=CascadeType.ALL)
private Deity father;
@OneToMany(cascade=CascadeType.ALL)
private Set<Deity> children;
public static enum Gender { MALE, FEMALE }
public Deity(String name, Gender gender) {
this.name = name;
this.gender = gender;
}
//////////////////////////
// Business methods follow
//////////////////////////
/**
* She's having a baby...
*
* @param childName the baby name
* @return the new child
*
* @throws IllegalArgumentException if the person is not a woman, or
* if the person is unmarried (illegitimate
* children are not yet supported)
*/
public Deity giveBirth(String childName, Deity childFather, Gender gender) {
if (this.gender != Gender.FEMALE)
throw new IllegalArgumentException("Only women can have children!");
if (childName == null)
throw new IllegalArgumentException("No child name!");
// create the child
Deity child = new Deity(childName, gender);
// set the parents in the children...
child.mother = this;
// add the child to this member's children
if (children == null)
children = new HashSet<>();
children.add(child);
if (childFather != null) {
child.father = childFather;
if (childFather.children == null)
childFather.children = new HashSet<>();
childFather.children.add(child);
}
return child;
}
////////////////////////////////////
// Property accessor methods follow
////////////////////////////////////
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Gender getGender() {
return this.gender;
}
public void setMother(Deity mother) {
this.mother = mother;
}
public Deity getMother() {
return this.mother;
}
public void setFather(Deity father) {
this.father = father;
}
public Deity getFather() {
return this.father;
}
public void setChildren(Set<Deity> children) {
this.children = children;
}
public Set<Deity> getChildren() {
return this.children;
}
}