Hibernate Embedded

hibernate

http://www.concretepage.com/hibernate/example-embeddedid-hibernate - done reading
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/EmbeddedId.html - done reading
https://stackoverflow.com/questions/3868515/difference-using-id-and-embeddedid-for-a-compound-key - done reading
http://memorynotfound.com/hibernate-embeddable-embedded-annotation-example/ - done reading
https://dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-component-using-annotations-1.html - done reading
http://www.thejavageek.com/2014/05/01/jpa-embeddedid-example/ - done reading
http://www.java2s.com/Code/Java/JPA/EmbeddedCompoundPrimaryKey.htm - done reading
https://www.youtube.com/watch?v=r8G_IH4wRtg
http://javabeat.net/embeddable-embedded-embeddedid-jpa-annotations/ - done reading

// @Embedded

The @Embedded annotation is both a class-level annotation and a field-level annotation.  When added to a 
model class, it tells Hibernate that this model object should be embedded inside another model object, and 
therefore Hibernate will not create a table for this model class. Inside the model class that contain this model 
object, we can add this same annotation ( @Embedded ) to the member variable that correspond to this 
embedded class.  The @Embedded annotation above the member variable is optional.  Hibernate will 
automatically look at the annotation coming from the embedded class.

For example, a person can multiple addresses, but must have at least one address or even none.  In a 
fully normalized database, we would probably have a table named Person, and a table named Address.  
However, the world is not perfect, and we may come across a software where we only have one table 
named Person, and the address information is also stored in this table.

// @EmbeddedId 

There may be a situation where a number of columns from an embedded object can be used together as the 
primary key. We cannot use embedded object with the @Id annotation. We have to use the @EmbeddedId 
annotation instead.

The @EmbeddedId is used for composite primary key. i.e. more than one column behaves jointly as primary 
key. We need to create an entity as Embeddable and the Embeddable entity can be embedded in other entity 
to achieve composite primary key. 

@Embeddable
public class Person implements Serializable {
  @Column(name="first_name")
  private String firstName;

  @Column(name="last_name")
  private String lastName;

  public Person(String firstName,String lastName){
    this.firstName=firstName;
    this.lastName=lastName;
  }
  public String getFirstName() {
    return firstName;
  }

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

  public String getLastName() {
    return lastName;
  }

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

@Entity
@Table(name="student")
public class Student implements Serializable {
  @EmbeddedId
  @AttributeOverride(name="firstName", column=@Column(name="f_name"))
  private Person id;

  @Column(name="location")
  private String location;

  public Student(Person id, String location){
    this.id=id;
    this.location=location;
  }
  public Person getId() {
    return id;
  }
  public void setId(Person id) {
    this.id = id;
  }
  public String getLocation() {
    return location;
  }
  public void setLocation(String location) {
    this.location = location;
  }
}

The @EmbeddedId annotation denotes a composite primary key that is an embeddable class. The embeddable class 
must be annotated as Embeddable.  The AttributeOverride annotation may be used to override the column mappings 
declared within the embeddable class.  The MapsId annotation may be used in conjunction with the EmbeddedId 
annotation to specify a derived primary key.

If the entity has a derived primary key, the AttributeOverride annotation may only be used to override those attributes of 
the embedded id that do not correspond to the relationship to the parent entity.

Relationship mappings defined within an embedded id class are not supported.

@Embeddable
public class DependentId {
   String name;
   EmployeeId empPK;   // corresponds to primary key type of Employee
}

@Entity
public class Dependent {
   // default column name for "name" attribute is overridden
   @AttributeOverride(name="name", @Column(name="dep_name"))
   @EmbeddedId DependentId id;
   ...
   @MapsId("empPK")
   @ManyToOne Employee emp;
}

In the above code, we have DependentId, a @Embeddable class, and we have the Dependent class, 
which is a normal class.  The Dependent class contains the id field, which is an instance of the 
DependentId class.

@Embeddable
public class Address {

    private String street;
    private String city;
    private String zip;
    private String state;

    public Address() {
    }

    public Address(String street, String city, String zip, String state) {
        street = street;
        this.city = city;
        this.zip = zip;
        this.state = state;
    }

    ...

    @Override
    public String toString() {
        return "Address{" +
                "street='" + street + '\'' +
                ", city='" + city + '\'' +
                ", zip='" + zip + '\'' +
                ", state='" + state + '\'' +
                '}';
    }
}

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    @Embedded
    @AttributeOverrides(value = {
            @AttributeOverride(name = "zip", column = @Column(length = 10)),
            @AttributeOverride(name = "city", column = @Column(nullable = false))
    })
    private Address address;

    public Person() {
    }

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public Integer getId() {
        return id;
    }

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

    ...

    public Address getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

package com.thejavageek.jpa.entities;
import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class EmployeeId implements Serializable {

    private int idEmployee;
    private String branchName;

    public EmployeeId() {

    }

    public EmployeeId(String branchName, int idEmployee) {
        this.branchName = branchName;
        this.idEmployee = idEmployee;
    }
}

@Entity
public class Employee {

    @EmbeddedId
    private EmployeeId id;

    private String firstName;
    private String lastName;
    private int salary;

    public EmployeeId getId() {
        return id;
    }

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

    public String getFirstName() {
        return firstName;
    }

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

EmployeeId id = new EmployeeId("pune", 1);
Employee emp = em.find(Employee.class, id);
System.out.println("First name = " + emp.getFirstName() + " "
    + "Last Name = " + emp.getLastName() + " " + "salary = "
    + emp.getSalary());

// Override column names for embedded object
@Embedded
@AttributeOverrides({
  @AttributeOverride (name="street", column=@Column(name="HOME_STREET_NAME")),
  @AttributeOverride (name="city", column=@Column(name="HOME_CITY_NAME"))
})
private Address homeAddress;
private Address officeAddress;
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License