Lazy Initialized对象加载没有使用hibernate Spring获取 [英] Lazy Initialized object load without fetch with hibernate Spring

查看:130
本文介绍了Lazy Initialized对象加载没有使用hibernate Spring获取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SchoolDto

    @Id
    @Column(name = "c_sm_npk_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "school_sequence")
    @SequenceGenerator(name = "school_sequence", sequenceName = "t_school_master_c_sm_npk_id_seq", initialValue = 1, allocationSize = 1)
    private Long id;
    @Column(name="c_sm_vnm_name")
    private String name;
    @ManyToOne(cascade = {CascadeType.MERGE},fetch=FetchType.LAZY)
    UserDto owner;

   /*Many other fileds omit for simplicity with getter/setter methods*/

UserDto

public class UserDto implements Serializable {
    private static final long serialVersionUID = 1L;

    public UserDto() {
    }

    @Id
    @Column(name = "c_um_npk_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
    @SequenceGenerator(name = "user_sequence", sequenceName = "t_user_master_c_um_npk_id_seq", initialValue = 1, allocationSize = 1)
    private Long id;
    @Column(name = "c_um_vnm_username", nullable = false)
    private String username;
    @Column(name = "c_um_vnm_email_address")
    private String emailId;
    @JsonSerialize(using = JsonDateSerializer.class)
    @Column(name = "c_um_dnm_birth_date",nullable=false)
    @Temporal(TemporalType.DATE)
    private Date birthdate;
    @Column(name="c_um_nnm_age",nullable=false)

    private int age;
    @Column(name = "c_um_vnm_first_name")
    private String firstName;
    @Column(name = "c_um_vnm_last_name")
    private String lastName;
    @Column(name = "c_um_vnm_mobile_number")
    private String mobileNumber;
    @Column(name = "c_um_vnm_gender")
    private String gender;
    @JsonManagedReference("user-role")
    @OneToMany(mappedBy = "userDto", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<RoleDto> roleDtos;
 /* getter setter of properties */
}

在这里,我有将所有者定义为Lazy集合。但是当我试图找到以下所有学校时:

Here, I have defined owner as Lazy collection. but when I try to find all schools as below:

public List<SchoolDto> getAllSchoolsWithAdvanceSearch(SchoolSearchDto schoolSearchDto) {
        return getEntityManager().createQuery("SELECT s from SchoolDto s").setFirstResult(schoolSearchDto.getFrom()).setMaxResults(schoolSearchDto.getSize()).getResultList();
    }

此学校返回列表及其所有者信息,包括所有者的角色(这又是Lazy集合形式UserDto),当我记录hibernate查询时,我只得到一个如下所示:

this return list of schools, with all its owner info including roles of the owner (which is again Lazy collection form UserDto) , when I log the hibernate query,I get only one select as below:

select
        schooldto0_.c_sm_npk_id as c1_24_,
        schooldto0_.c_sm_vnm_address_line_1 as c2_24_,
        schooldto0_.owner_c_um_npk_id as owner17_24_
    from
        t_school_master schooldto0_

在搜索过程中,我发现它可能是Jackson序列化问题,所以我按照 jackson - 不要序列化懒惰对象& 避免杰克逊对未获取的懒惰对象进行序列化,如下所示

during search, I come across that it may be Jackson serialization issue, so I did below changes as per jackson - do not serialize lazy objects & Avoid Jackson serialization on non fetched lazy objects as below

application-servlet.xml

    <mvc:annotation-driven>
        <mvc:message-converters>
            <ref bean="jsonHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>


       <bean id="jsonHttpMessageConverter"  class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.util.HibernateAwareObjectMapper" />
                </property>
            </bean>

HibernateAwareObjectMapper.java

public HibernateAwareObjectMapper() {
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        Hibernate4Module module = new Hibernate4Module();
        module.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
        module.disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
        registerModule(module);
    }

注意:我稍后需要所有者详细信息,因此我无法将其标记为 @JsonIgnore

Note : I need owner detail later, so I can not mark it as @JsonIgnore.

请帮我解决这个问题。提前致谢

Please help me to solve this issue. Thanks in advance

编辑:当前输出

0:  {
       "id": 1
       "name": "school1"
       "address1": null
       owner : {
           "id" : 1,
           "firstName": "Rutesha",
           "lastName" : "Patel",
           "roles":[{
                "name" : "SCHOOL_ADMIN"
            }]
       }
}

编辑:预期输出

0:  {
       "id": 1
       "name": "school1"
       "address1": null
}

OR 

0:  {
       "id": 1
       "name": "school1"
       "address1": null
       owner : null
}


推荐答案

执行以下更改

return getEntityManager().createQuery("SELECT s.id,s.name,s.address1 from SchoolDto s").setFirstResult(schoolSearchDto.getFrom()).setMaxResults(schoolSearchDto.getS‌​ize()).getResultList(); 

@ManyToOne - 就像注释一样文档存在同样的问题,但在这种情况下,JPA提供者更有可能会考虑FetchType提示。

@ManyToOne - like annotations have according to the documentation the same problem, but in that case it much more likely that the JPA provider will consider the FetchType hint.

@ManyToOne(cascade={CascadeType.MERGE},optional = false,fetch=FetchType.LAZY )
UserDto owner;

注释后面也可以提供帮助。

Also following annotations can help.

@OneToMany(fetch = FetchType.LAZY, mappedBy = "owner")
@Cascade(CascadeType.ALL)
@Fetch(FetchMode.SELECT)
@BatchSize(size = 10)

可能 @JoinColumn(name =other_entity_fk应使用)

例如

@ManyToOne(fetch = FetchType.LAZY)
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name = "STOCK_ID", nullable = false)
public Stock getStock() {
    return this.stock;
}

参考获取模式的策略

这篇关于Lazy Initialized对象加载没有使用hibernate Spring获取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆