The method EntityManager.getReference() can be useful, to initialize an associations like @ManyToOne or @OneToOne with already exiting target entity without loading it's fields from the database.
Example
Following example shows initializing and persisting @OneToOne relationship with getReference() method.
The Entities
@Entity
public class Employee {
@Id
@GeneratedValue
private Integer id;
private String name;
@OneToOne
private Task task;
.............
}
@Entity
public class Task {
@Id
@GeneratedValue
private Integer id;
private String name;
.............
}
Using getReference() method
public class GetReferenceExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("example-unit");
try {
persistTask(emf);
persistEmployee(emf);
allEmployeesQuery(emf);
} finally {
emf.close();
}
}
private static void persistTask(EntityManagerFactory emf) {
System.out.println("-- persisting Task --");
Task task = new Task();
task.setName("test task");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(task);
em.getTransaction().commit();
em.close();
System.out.println("Task persisted: " + task);
}
private static void persistEmployee(EntityManagerFactory emf) {
System.out.println("-- persisting employee --");
Employee employee = new Employee();
employee.setName("Joe");
EntityManager em = emf.createEntityManager();
Task task = em.getReference(Task.class, 1);
employee.setTask(task);
em.getTransaction().begin();
em.persist(employee);
em.getTransaction().commit();
em.close();
System.out.println("Employee persisted: " + employee);
}
private static void allEmployeesQuery(EntityManagerFactory emf) {
System.out.println("-- select all employee query --");
EntityManager em = emf.createEntityManager();
Query query = em.createQuery("select t from Employee t");
List<Employee> resultList = query.getResultList();
for (Employee employee : resultList) {
System.out.println(employee + " " + employee.getTask());
}
}
} Hibernate: create sequence hibernate_sequence start with 1 increment by 1 Hibernate: create table Employee (id integer not null, name varchar(255), task_id integer, primary key (id)) Hibernate: create table Task (id integer not null, name varchar(255), primary key (id)) Hibernate: alter table Employee add constraint FKknovwluxttletr14l9atj112y foreign key (task_id) references Task -- persisting Task -- Hibernate: call next value for hibernate_sequence Hibernate: insert into Task (name, id) values (?, ?) Task persisted: Task{id=1, name='test task'} -- persisting employee -- Hibernate: call next value for hibernate_sequence Hibernate: insert into Employee (name, task_id, id) values (?, ?, ?) Employee persisted: Employee{id=2, name='Joe'} -- select all employee query -- Hibernate: select employee0_.id as id1_0_, employee0_.name as name2_0_, employee0_.task_id as task_id3_0_ from Employee employee0_ Hibernate: select task0_.id as id1_1_0_, task0_.name as name2_1_0_ from Task task0_ where task0_.id=? Employee{id=2, name='Joe'} Task{id=1, name='test task'}
As seen above in hibernate query logs, Task's fields were never loaded via 'select' statement during persisting employee (in persistEmployee() method) and only task id (the foreign key) was used to persist the association.
Check out next example of getReference() with @ManyToOne.
Example ProjectDependencies and Technologies Used: - h2 1.4.196: H2 Database Engine.
- hibernate-core 5.2.10.Final: The core O/RM functionality as provided by Hibernate.
Implements javax.persistence:javax.persistence-api version 2.1 - JDK 1.8
- Maven 3.3.9
|