简体   繁体   English

休眠许多渴望获取不工作的人

[英]Hibernate many to one eager fetching not working

I am trying to fetch data from database using hibernate annotation but it is not working as my expected. 我正在尝试使用休眠注释从数据库中获取数据,但是它没有按我的预期工作。 I have a two table Employee and Department. 我有两个表Employee和Department。 the java code is as below : Java代码如下:

Employee class 员工阶层

 @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 
    }

Department class : 部门类别:

@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.
}

spring-servlet.xml file : spring-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>

when i trying to fetch all data from employee and department table but it only returns the data from employee table my code for hit hql query as below : 当我尝试从employee和department表中获取所有数据,但它仅从employee表中返回数据时,我的命中hql查询的代码如下:

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

above query is hit as below on database. 上面的查询在数据库上命中如下。

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_

But i want all data of the employee table and department table using Eager fetching. 但是我想使用Eager访存来获取雇员表和部门表的所有数据。

It works as expected. 它按预期工作。 The EmployeeBO contains a DepartmentBO. EmployeeBO包含一个DepartmentBO。 The DepartmentBO will automatically be filled the moment you access it. 当您访问DepartmentBO时,它会自动填充。

This is not true, if the Hibernate session containing the EmployeeBO has ended. 如果包含EmployeeBO的休眠会话已结束,则情况并非如此。 Then the EmployeeBO is transient and hibernate will not fetch the missing object. 然后,EmployeeBO是瞬态的,休眠状态将不会获取丢失的对象。

To enforce filling the DepartmentBO, you can add a fetch clause to your hql code. 要强制填充DepartmentBO,可以在hql代码中添加fetch子句。 But that is not lazy fetching any more. 但这不再是懒惰获取。

The HQL 总部

from EmployeeBO join fetch EmployeeBO.department 

should do the job (replace the EmployeeBO with the actual entity name). 应该做的工作(用实际的实体名称替换EmployeeBO)。

See here in the hibernate docs: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html and for the fetching strategies here https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching 请参阅hibernate文档中的此处: https : //docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html以及此处的获取策略https://docs.jboss.org/hibernate/ orm / 3.3 / reference / zh-CN / html / performance.html#performance-fetching

From the comments, you actually want eager fetching on the relationship, so you need to declare the fetchtype to be eager: 从注释中,您实际上想渴望获取关系,因此您需要声明fetchtype渴望:

@ManyToOne(fetch=FetchType.EAGER)

should fix it. 应该修复它。 Adding another doc here: https://docs.oracle.com/javaee/6/api/javax/persistence/ManyToOne.html 在此处添加另一个文档: https : //docs.oracle.com/javaee/6/api/javax/persistence/ManyToOne.html

有两种方法可以执行此操作:1)使用EAGER访存类型2)在获得雇员后,在每个雇员上调用getDepartmentBO()

I think you have missed the anotation for lazy loading. 我认为您已经错过了延迟加载的注释。

You have to use (fetch=FetchType.LAZY) on a association which you want to lazy load 您必须在要延迟加载的关联上使用(fetch = FetchType.LAZY)

Hibernate by default has Lazy loading. 休眠默认情况下具有延迟加载。 ie it would not fetch the data of another table. 即它不会获取另一个表的数据。 In you case if you want the data of department table, you will have to call getter of departmentBO if you are in hibernate session. 在这种情况下,如果要获取部门表的数据,则在休眠会话中必须调用部门 BO的getter。 Note: it will fire another query. 注意:它将触发另一个查询。 else you can also use 否则你也可以使用

Hibernate.initialize(entity.getdepartmentBO())

If you want by default to get the department data. 默认情况下是否要获取部门数据。 use the following code 使用以下代码

@ManyToOne(fetch=FetchType.EAGER)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM