2015-04-09 3 views
0

Я пытаюсь извлечь данные из базы данных с помощью аннотации спящего режима, но он не работает как ожидаемый. У меня есть два сотрудника и отдел. код Java, как показано ниже:Спящий режим от одного до одного нетерпения не работает

класс Employee класс

@Entity 
    @Table(name = "EMPLOYEE")   
    public class EmployeeBO { 

     @Id 
     @GeneratedValue(strategy=GenerationType.IDENTITY) 
     @Column(name = "EMPID") 
     private int empId; 
     @Column(name = "EMPNAME") 
     private String empName; 
     @Column(name = "SALARY") 
     private int empSalary; 
     @Column(name = "EMPADDRESS") 
     private String empAddress; 
     @Column(name = "EMPAGE") 
     private int empAge; 
     @Column(name = "DEPTID") 
     private Integer deptId; 
     @ManyToOne(fetch=FetchType.EAGER) 
     @JoinColumn(name="DEPTID", nullable = true, insertable = false, updatable = false) 
     private DepartmentBO departmentBO; 
// getter and setter 
    } 

Факультет:

@Entity 
@Table(name = "DEPARTMENT") 
public class DepartmentBO { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name = "DEPTID") 
    private int deptid; 

    @Column(name = "DEPTNAME") 
    private String deptName; 
    // getter and setter. 
} 

весна-servlet.xml файл:

<?xml version="1.0" encoding="UTF-8"?> 
<!--?xml version="1.0" encoding="UTF-8"?--> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 


    <context:annotation-config></context:annotation-config> 

    <context:component-scan base-package="com.web"></context:component-scan> 

    <context:property-placeholder location="file:D:/EasyProp/db.properties" ignore-unresolvable="false"/> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/jsp/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

    <bean id="basicDataSource" 
     class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 

     <property name="driverClassName" value="${driver.classname}" /> 
     <property name="url" value="${driver.url}" /> 
     <property name="username" value="${username}" /> 
     <property name="password" value="${password}" /> 
<!--  <property name="initialSize" value="10"/> --> 
<!--   <property name="maxActive" value="25"/> --> 
<!--   <property name="maxIdle" value="25"/> --> 
     <!-- <aop:scoped-proxy/> --> 
    </bean> 
    <tx:annotation-driven /> 
    <bean id="transactionManager" 
     class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="mySessionFactory" /> 
    </bean> 

    <!-- <bean id="dbUtil" class="com.web.utility.OnLoadStartUp" init-method="initialize"> 
     <property name="dataSource" ref="basicDataSource" /> 
    </bean> --> 

    <!-- <bean id="loadOnStartUp" class="com.web.utility.LoadOnStartUp"> 
     <property name="baseService" ref="baseService"></property> 
    </bean> --> 

    <bean id="mySessionFactory" 
     class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
     <property name="dataSource" ref="basicDataSource" /> 
     <property name="annotatedClasses"> 
      <list> 
       <value>com.web.bo.EmployeeBO</value> 
       <value>com.web.bo.DepartmentBO</value> 
      </list> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.hmb2ddl.auto">validate</prop> 
       <prop key="hibernate.generate_statistics">true</prop> 
       <prop key="hibernate.jdbc.fetch_size">10</prop> 
       <prop key="hibernate.jdbc.batch_size">25</prop> 
       <prop key="hibernate.jdbc.batch_versioned_data">true</prop> 
       <prop key="hibernate.max_fetch_depth">3</prop> 
       <prop key="hibernate.default_batch_fetch_size">8</prop> 
       <prop key="hibernate.order_updates">true</prop> 
       <prop key="hibernate.connection.release_mode">on_close</prop> 
       <prop key="hibernate.bytecode.use_reflection_optimizer">true</prop> 
       <prop key="hibernate.bytecode.provider">javassist</prop>     
      </props> 
     </property> 
    </bean> 
</beans> 

, когда я пытаюсь извлечь все данные из таблицы сотрудников и департаментов, но он возвращает только данные из таблицы сотрудников моего кода для запроса hql для запроса как ниже:

List<EmployeeBO> empList = null; 
     empList = sessionFactory.getCurrentSession().createQuery("From "+employeeBO.getClass().getName()).list(); 

запрос выше, как указано ниже в базе данных.

select employeebo0_.EMPID as EMPID0_, employeebo0_.DEPTID as DEPTID0_, employeebo0_.EMPADDRESS as EMPADDRESS0_, employeebo0_.EMPAGE as EMPAGE0_, employeebo0_.EMPNAME as EMPNAME0_, employeebo0_.SALARY as SALARY0_ from EMPLOYEE employeebo0_ 

Но я хочу, чтобы все данные сотрудника таблица и отдел таблицы, используя нетерпеливую выборку.

+2

Итак, вы не хотите, чтобы ленивый выбор, но с нетерпением, верно? Ленивая выборка заключается именно в том, что НЕ собирает информацию отдела до тех пор, пока вам это не понадобится. –

ответ

0

Есть два способа сделать это: 1) использует EAGER типа 2 выборки) называет getDepartmentBO() на каждом работник после получения работника

0

Я думаю, вы пропустили эту заметку для отложенной загрузки.

Вы должны использовать (скачивает = FetchType.LAZY) на ассоциацию, которое вы хотите ленивым нагрузки

+0

LAZY - тип выборки по умолчанию для коллекций – HJK

1

Он работает, как ожидалось. EmployeeBO содержит отдел BO. ОтделBOBO будет автоматически заполнен в тот момент, когда вы его получите.

Это неправда, если сессия Hibernate, содержащая EmployeeBO, закончилась. Затем EmployeeBO является переходным процессом, а спящий режим не будет получать недостающий объект.

Чтобы принудительно заполнить DepartmentBO, вы можете добавить предложение fetch к вашему hql-коду. Но это уже не ленивый выбор.

HQL

from EmployeeBO join fetch EmployeeBO.department 

должен делать эту работу (заменить EmployeeBO с действительным именем объекта).

Смотрите здесь в Hibernate документах: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html и для кокетливых стратегий здесь https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching

Из комментариев, вы на самом деле хотите нетерпеливыми выборки на отношениях, так что вы должны объявить fetchtype быть готовы:

@ManyToOne(fetch=FetchType.EAGER) 

следует исправить. Добавление другого документа здесь: https://docs.oracle.com/javaee/6/api/javax/persistence/ManyToOne.html

+0

Да, я знаю, что DepartmentBO будет автоматически заполняться, но он не заполняется, когда я нажимаю запрос. не могли бы вы объяснить свой второй пункт о сеансе. –

+0

Lazy fetching - это именно то, что вы получаете только то, о чем вы явно просили. Любая смежная структура выбирается в тот момент, когда вам это нужно. То, что вы хотите (полностью заполненная структура с одним SQL), называется нетерпеливой выборкой. – thst

+0

Hibernate работает с прокси-объектами, которые содержат фактические данные и управляют загрузкой недостающих частей. Прокси-сервер может получить доступ только к любым недостающим частям, если он находится внутри сеанса спящего режима. Как только сессия закончится, прокси может получить доступ только к тем частям объекта, которые уже существуют. Это важно, если вы отправляете данные в другой поток для обработки или управления сеансом самостоятельно. См. Здесь для жизненного цикла объекта спящего режима https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html, если вы это сделаете в Google, вы найдете множество обучающих программ. – thst

0

Hibernate по умолчанию имеет ленивую загрузку. то есть он не будет получать данные другой таблицы.В случае, если вам нужны данные таблицы отделов, вам нужно будет позвонить получателю departmentBO, если вы находитесь в сеансе спящего режима. Примечание: он вызывает другой запрос. иначе вы также можете использовать

Hibernate.initialize(entity.getdepartmentBO()) 

Если вы хотите по умолчанию получить данные отдела. используйте следующий код:

@ManyToOne(fetch=FetchType.EAGER) 
+0

ohk Я хочу по умолчанию получить данные отдела, и я также добавил код, как вы упомянули, но все же он не работает. –

+0

Можете ли вы рассказать мне, какой запрос он сейчас стреляет? включает ли это соединение в отдел? –

+0

У меня есть только добавленный код, как вы упомянули. мой вопрос, как указано выше. –

Смежные вопросы