2017-02-05 4 views
1

Я использую JPA 2.0 с поставщиком непрерывности EclipseLink и менеджером сущностей Hibernate 4.3.10.Final. У меня есть отношения @ManyToOne между сущностями Employee и Office. Я ввожу нового сотрудника с помощью EntityManagerFactory. Экземпляр сотрудника ссылается на существующий Office.The код работает, но запросы показывают, что он извлекает все столбцы Office вместо officeId. Как я могу точно настроить запросы, чтобы избежать выборки всех столбцов Office при вставке нового сотрудника? Я попытался использовать FetchType.LAZY в @ManyToOne, но он не работает.@ManyToOne извлекает все столбцы таблицы соединений при вставке новой записи

Employee.java

@Entity 
public class Employee { 

    @Id 
    @SequenceGenerator(name="employeeSequence",allocationSize=1, sequenceName="EMP_SEQ")  
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="employeeSequence") 
    private int empId; 

    @Column(name="FIRST_NAME") 
    private String firstName; 

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

    @Column(name="DOB") 
    private Date dateOfBirth; 

    private Date hireDate; 

    @ManyToOne 
    @JoinColumn(name="location") 
    private int location; 

Office.java

@Entity 
public class Office { 
    @Id 
    private int officeId; 

    private String location; 
    private String address1; 
    private String address2; 
    private String city; 
    private String state; 
    private String country; 
    private String zipcode; 

код, который создает объект Employee

Employee emp = new Employee(); 
emp.setFirstName(firstName);   
emp.setLastName(lastName); 
emp.setDateOfBirth(dob); 
emp.setHireDate(hiredate); 

Office office = new Office(); 
office.setOfficeId(officeId); 
emp.setLocation(office); 

SQL запросов

Hibernate: 
select 
    EMP_SEQ.nextval 
from 
    dual 

Hibernate: 
select 
    office_.officeId, 
    office_.address1 as address2_1_, 
    office_.address2 as address3_1_, 
    office_.city as city4_1_, 
    office_.country as country5_1_, 
    office_.location as location6_1_, 
    office_.state as state7_1_, 
    office_.zipcode as zipcode8_1_ 
from 
    Office office_ 
where 
    office_.officeId=? 

Hibernate: 
insert 
into 
    Emp 
    (DOB, FIRST_NAME, hireDate, LAST_NAME, location, empId) 
values (?, ?, ?, ?, ?, ?) 

ответ

0

Это довольно общие для разработчиков запросов к их базе данных на основе некоторых внешнего ключа значение, чтобы получить постоянные экземпляры отношений, когда они спасают новый объект, что-то вроде следующего:

@Entity 
public class Employee { 
    // other stuff removed for breavity 
    @ManyToOne 
    private Office office; 
} 

@Entity 
public class Office { 
    // no relationship back to Employee 
} 

// some repository method 
public Employee save(String employeeName, Long officeId) { 
    final Office office = entityManager.find(Office.class, offceId); 
    final Employee employee = new Employee(employeeName, officeId); 
    entityManager.persist(employee); 
    return employee; 
} 

В этом случае , поставщик постоянства будет запрашивать базу данных для построения объекта Office, все с целью связывания идентификатора с Employee при сохранении. Как вы заметили, это не только необязательно, но и может повлиять на производительность.

Другим решением, позволяющим избежать извлечения базы данных, было бы использовать либо Session#load с точки зрения собственного Hibernate API, либо EntityManager#getReference для JPA. Во всех смыслах и целях они являются синонимами в том смысле, что они принимают значение класса и первичного ключа и создают прокси-сервер, который представляет тип класса, внутреннее состояние которого будет загружаться лениво при доступе.

Так путем изменения метода хранилища выше:

// some repository method 
public Employee save(String employeeName, Long officeId) { 
    final Office office = entityManager.getReference(Office.class, offceId); 
    final Employee employee = new Employee(employeeName, officeId); 
    entityManager.persist(employee); 
    return employee; 
} 

Там больше не должно быть выборки против хранилища данных для Office.

+0

Спасибо Naros. Это работает. –