diff --git a/Doc/course.xml b/Doc/course.xml index 6ff75c0931366b126f26757d2ef6f07d97c15200..53a3ce0097b20467e59081a4aaf0c8946b889115 100644 --- a/Doc/course.xml +++ b/Doc/course.xml @@ -18011,7 +18011,7 @@ CREATE TABLE BankAccount ( </chapter> <chapter xml:id="mappingRelatedEntities"> - <title>Mapping related entities</title> + <title>Mapping related Components and entities</title> <section xml:id="primaryKeyRevisit"> <title>Primary keys revisited</title> @@ -18768,8 +18768,8 @@ public class Persist { </orderedlist> <para>After successfully inserting these three entities - <personname>Eve Blix</personname> may no longer be entitled to use her - laptop. We decouple these two entities:</para> + <personname>Eve Blix</personname> shall no longer be entitled to use + her laptop. We thus decouple these two entities:</para> <programlisting>package entity.company2; public class LoadAndDeRegister { @@ -18783,6 +18783,27 @@ public class LoadAndDeRegister { <para>All three entities are still present in our database but the corresponding foreign key has been set to <code>NULL</code>.</para> + + <qandaset role="exercise"> + <title>One laptop per employee</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider a company where each employee must have a + laptop being assigned and modify the mapping in + <classname>entity.company2.Employee</classname> + accordingly.</para> + </question> + + <answer> + <para>See <emphasis + role="bold">@OneToOne(optional=false,...</emphasis> in + <classname>entity.company3.Employee</classname>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> </section> </chapter> </part> diff --git a/ws/eclipse/HibIntro/src/main/java/entity/company3/Employee.java b/ws/eclipse/HibIntro/src/main/java/entity/company3/Employee.java new file mode 100644 index 0000000000000000000000000000000000000000..c7bd76914fe7c6378b1f5f0b45a8287915764cbb --- /dev/null +++ b/ws/eclipse/HibIntro/src/main/java/entity/company3/Employee.java @@ -0,0 +1,71 @@ +package entity.company3; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +/** + * + * {@link Employee} instances related to {@link Department} + * + */ +@Entity +@Table(uniqueConstraints={@UniqueConstraint(columnNames={"staffNumber"})}) +public class Employee { + + @Id + @GeneratedValue + public Long getId() {return id;} + protected void setId(Long id) {this.id = id;} + private Long id; + + public int getStaffNumber() { return staffNumber;} + public void setStaffNumber(int staffNumber) { this.staffNumber = staffNumber;} + int staffNumber = Integer.MIN_VALUE; + + public String getCname() { return cname;} + public void setCname(String cname) { this.cname = cname;} + private String cname; // Common name + + /** + * One laptop per {@link Employee}. + * + * @return Laptop "owned" by {@link Employee}. + */ + @OneToOne(optional=false, cascade={CascadeType.ALL}) + public Laptop getLaptop() { return laptop;} + public void setLaptop(Laptop laptop) {this.laptop = laptop;} + private Laptop laptop;// Workstation for employees. + + protected Employee(){} + + public Employee(final int staffNumber, final String cname) { + setStaffNumber(staffNumber); + setCname(cname); + } + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } else if (Integer.MIN_VALUE == getStaffNumber()) { + return false; + } else if (other instanceof Employee) { + final Employee that = (Employee) other; + return this.getStaffNumber() == that.getStaffNumber(); + } else { + return false; + } + } + @Override + public int hashCode() { + if (Integer.MIN_VALUE == getStaffNumber()) { + return System.identityHashCode(this); + } else { + return getStaffNumber(); + } + } +} \ No newline at end of file diff --git a/ws/eclipse/HibIntro/src/main/java/entity/company3/Laptop.java b/ws/eclipse/HibIntro/src/main/java/entity/company3/Laptop.java new file mode 100644 index 0000000000000000000000000000000000000000..c53d327d4665542f9aaacc47b7d87fc331d643e5 --- /dev/null +++ b/ws/eclipse/HibIntro/src/main/java/entity/company3/Laptop.java @@ -0,0 +1,57 @@ +package entity.company3; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +/** + * + * Laptops possibly being assigned to {@link Employee} + * + */ +@Entity +@Table(uniqueConstraints={@UniqueConstraint(columnNames={"idNumber"})}) +public class Laptop { + + @Id + @GeneratedValue + public Long getId() {return id;} + protected void setId(Long id) {this.id = id;} + private Long id; + + /** + * @return The device's unique part number + */ + public int getIdNumber() { return idNumber;} + public void setIdNumber(int idNumber) { this.idNumber = idNumber;} + int idNumber; + + protected Laptop(){} + + public Laptop(final int idNumber) { + setIdNumber(idNumber); + } + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } else if (Integer.MIN_VALUE == getIdNumber()) { + return false; + } else if (other instanceof Laptop) { + final Laptop that = (Laptop) other; + return this.getIdNumber() == that.getIdNumber(); + } else { + return false; + } + } + @Override + public int hashCode() { + if (Integer.MIN_VALUE == getIdNumber()) { + return System.identityHashCode(this); + } else { + return getIdNumber(); + } + } +} \ No newline at end of file diff --git a/ws/eclipse/HibIntro/src/main/java/entity/company3/LoadAndDeRegister.java b/ws/eclipse/HibIntro/src/main/java/entity/company3/LoadAndDeRegister.java new file mode 100644 index 0000000000000000000000000000000000000000..55e3deff4b701a34b6d849856016101c6a868575 --- /dev/null +++ b/ws/eclipse/HibIntro/src/main/java/entity/company3/LoadAndDeRegister.java @@ -0,0 +1,26 @@ +package entity.company3; + +import hibintro.util.HibernateUtil; + +import org.hibernate.Session; +import org.hibernate.Transaction; + +/** + * Removing {@link Laptop} from {@link Employee} + */ +public class LoadAndDeRegister { + /** + * @param args not used. + */ + public static void main(String[] args) { + final Session session = HibernateUtil.createSessionFactory("entity/company2/hibernate.cfg.xml").openSession(); + { + final Transaction transaction = session.beginTransaction(); + final Employee eve = (Employee) session.load(Employee.class, 2L); + + eve.setLaptop(null); + + transaction.commit(); + } + } +} \ No newline at end of file diff --git a/ws/eclipse/HibIntro/src/main/java/entity/company3/Persist.java b/ws/eclipse/HibIntro/src/main/java/entity/company3/Persist.java new file mode 100644 index 0000000000000000000000000000000000000000..e4a3e1f89b5b64ebfdbbb7288b048a9ee021039b --- /dev/null +++ b/ws/eclipse/HibIntro/src/main/java/entity/company3/Persist.java @@ -0,0 +1,33 @@ +package entity.company3; + +import hibintro.util.HibernateUtil; + +import org.hibernate.Session; +import org.hibernate.Transaction; + +/** + * Persisting {@link Employee} possibly along with + * personal assigned laptops. + */ +public class Persist { + /** + * @param args not used. + */ + public static void main(String[] args) { + final Session session = HibernateUtil.createSessionFactory("entity/company3/hibernate.cfg.xml").openSession(); + { + final Transaction transaction = session.beginTransaction(); + final Employee martin = new Employee(123, "Martin Goik"), + eve = new Employee(140, "Eve Blix"); + + final Laptop superCoolGadget = new Laptop(2213); + eve.setLaptop(superCoolGadget); + // Now only save the employee transients, + // superCoolGadget will be saved automatically due to + // CascadeType.ALL + session.save(martin); + session.save(eve); + transaction.commit(); + } + } +} \ No newline at end of file diff --git a/ws/eclipse/HibIntro/src/main/java/entity/company3/hibernate.cfg.xml b/ws/eclipse/HibIntro/src/main/java/entity/company3/hibernate.cfg.xml new file mode 100644 index 0000000000000000000000000000000000000000..78e99b2113fee9c8bace82bd96e1d9f2046a2aeb --- /dev/null +++ b/ws/eclipse/HibIntro/src/main/java/entity/company3/hibernate.cfg.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE hibernate-configuration PUBLIC + "-//Hibernate/Hibernate Configuration DTD 3.0//EN" + "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> + +<hibernate-configuration> + <session-factory > + <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> + <property name="hibernate.connection.password">XYZ</property> + <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hdm</property> + <property name="hibernate.connection.username">hdmuser</property> + <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> + <property name="hibernate.show_sql">false</property> + <property name="hibernate.format_sql">true</property> + <property name="hibernate.hbm2ddl.auto">update</property> + + <mapping class="entity.company3.Laptop"/> + <mapping class="entity.company3.Employee"/> + </session-factory> +</hibernate-configuration>