Java Hibernate-设置对象属性时避免冗余查询

Java Hibernate-设置对象属性时避免冗余查询,java,hibernate,set,query-optimization,Java,Hibernate,Set,Query Optimization,我有两个实体,分别是Product和Customer。它们之间存在多对一关系,这意味着一个客户可以拥有多个产品,而一个产品只能属于一个客户。因此,在我的产品类别中,我有: @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "account_holder", nullable = false) public Customer getCustomer(){ return customer; } 在我的客户类别中,我有: @OneTo

我有两个实体,分别是Product和Customer。它们之间存在多对一关系,这意味着一个客户可以拥有多个产品,而一个产品只能属于一个客户。因此,在我的产品类别中,我有:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "account_holder", nullable = false)
public Customer getCustomer(){
    return customer;
}
在我的客户类别中,我有:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Product> getProducts() {
    return products;
}
现在我的问题是,设置此产品的客户会导致运行许多不必要的查询。只有在我尝试设置客户时才会发生这种情况。我想知道是否有办法避免这种情况。谢谢你在这方面的帮助

以下是我的getCustomer方法:

public Customer getCustomer(long id)
{
    return (Customer) session.load(Customer.class, id);
}
以及我的产品类别:

private static final long serialVersionUID = -7982984161342095617L;

private int id;
private long accNumber;
private String name;
private double accLimit;
private Status status;
private Customer customer;

/**
 * @return the id
 */
@Id
@GeneratedValue
@Column(name="id", unique = true, nullable = false)
public int getId() {
    return id;
}

/**
 * @return the accNumber
 */
@Column(name="account_num")
public long getAccNumber() {
    return accNumber;
}

/**
 * @return the productName
 */
@Column(name="product_name")
public String getName() {
    return name;
}

/**
 * @return the accLimit
 */
@Column(name="account_limit")
public double getAccLimit() {
    return accLimit;
}

/**
 * @return the status
 */
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="status")
public Status getStatus() {
    return status;
}

/**
 * @return the customer
 */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "account_holder", nullable = false)
public Customer getCustomer(){
    return customer;
}

/**
 * @param id the id to set
 */
public void setId(int id) {
    this.id = id;
}

/**
 * @param accNumber the accNumber to set
 */
public void setAccNumber(long accNumber) {
    this.accNumber = accNumber;
}

/**
 * @param productName the productName to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @param accLimit the accLimit to set
 */
public void setAccLimit(double accLimit) {
    this.accLimit = accLimit;
}

/**
 * @param status the status to set
 */
public void setStatus(Status status) {
    this.status = status;
}

/**
 * @param customer the customer to set
 */
public void setCustomer(Customer customer)
{
    this.customer = customer;
}

@Entity
@Table(name="product_status")
public static class Status implements Serializable{


    private static final long serialVersionUID = 7844926322256321866L;
    private int id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name="id")
    public int getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

}
客户类别:

private static final long serialVersionUID = -1451775337978306021L;
private long id;
private Salutation salutation; 
private String firstName;
private String lastName;
private String prfdName;
private String nic;
private String passport;
private String mobileNum;
private String alterNum;
private String email;
private String addressLine1;
private String addressLine2;
private String addressLine3;
private String town;
private String district;
private long postalCode;
private Language prfdLanguage;
private Date joinDate;
private Date dob;
private String branch;
private String relManager;
private Status status;
private User creator;
private Date creationDate;
private Set<Interaction> interactions = new HashSet<Interaction>(0);
private Set<Product> products = new HashSet<Product>(0);



@Id
@GeneratedValue
@Column(name="id")
public long getId() {
    return id;
}

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="salutation")
public Salutation getSalutation() {
    return salutation;
}

@Column(name="first_name")
public String getFirstName() {
    return firstName;
}

@Column(name="last_name")
public String getLastName() {
    return lastName;
}

@Column(name="prfd_name")
public String getPrfdName() {
    return prfdName;
}

@Column(name="nic")
public String getNic() {
    return nic;
}

@Column(name="passport")
public String getPassport() {
    return passport;
}

@Column(name="mobile_num")
public String getMobileNum() {
    return mobileNum;
}

@Column(name="alter_num")
public String getAlterNum() {
    return alterNum;
}

@Column(name="email")
public String getEmail() {
    return email;
}

@Column(name="address_1")
public String getAddressLine1() {
    return addressLine1;
}

@Column(name="address_2")
public String getAddressLine2() {
    return addressLine2;
}

@Column(name="address_3")
public String getAddressLine3() {
    return addressLine3;
}

@Column(name="town")
public String getTown() {
    return town;
}

@Column(name="district")
public String getDistrict() {
    return district;
}

@Column(name="postal_code")
public long getPostalCode() {
    return postalCode;
}

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="prfd_language")
public Language getPrfdLanguage() {
    return prfdLanguage;
}

@Temporal(TemporalType.DATE)
@Column(name="join_date")
public Date getJoinDate() {
    return joinDate;
}

@Temporal(TemporalType.DATE)
@Column(name="dob")
public Date getDob() {
    return dob;
}

@Column(name="branch")
public String getBranch() {
    return branch;
}

@Column(name="rel_manager")
public String getRelManager() {
    return relManager;
}

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="status")
public Status getStatus() {
    return status;
}

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="created_by")
public User getCreator() {
    return creator;
}

@Temporal(TemporalType.DATE)
@Column(name="creation_date")
public Date getCreationDate() {
    return creationDate;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Interaction> getInteractions() {
    return interactions;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Product> getProducts() {
    return products;
}



public void setId(long id) {
    this.id = id;
}

public void setSalutation(Salutation salutation) {
    this.salutation = salutation;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public void setPrfdName(String prfdName) {
    this.prfdName = prfdName;
}

public void setNic(String nic) {
    this.nic = nic;
}

public void setPassport(String passport) {
    this.passport = passport;
}

public void setMobileNum(String mobileNum) {
    this.mobileNum = mobileNum;
}

public void setAlterNum(String alterNum) {
    this.alterNum = alterNum;
}

public void setEmail(String email) {
    this.email = email;
}

public void setAddressLine1(String addressLine1) {
    this.addressLine1 = addressLine1;
}

public void setAddressLine2(String addressLine2) {
    this.addressLine2 = addressLine2;
}

public void setAddressLine3(String addressLine3) {
    this.addressLine3 = addressLine3;
}

public void setTown(String town) {
    this.town = town;
}

public void setDistrict(String district) {
    this.district = district;
}

public void setPostalCode(long postalCode) {
    this.postalCode = postalCode;
}

public void setPrfdLanguage(Language prfdLanguage) {
    this.prfdLanguage = prfdLanguage;
}

public void setJoinDate(Date joinDate) {
    this.joinDate = joinDate;
}

public void setDob(Date dob) {
    this.dob = dob;
}

public void setBranch(String branch) {
    this.branch = branch;
}

public void setRelManager(String relManager) {
    this.relManager = relManager;
}

public void setStatus(Status status) {
    this.status = status;
}

public void setCreator(User creator) {
    this.creator = creator;
}

public void setCreationDate(Date creationDate) {
    this.creationDate = creationDate;
}

public void setInteractions(Set<Interaction> interactions) {
    this.interactions = interactions;
}

public void setProducts(Set<Product> products) {
    this.products = products;
}



@Entity
@Table(name="customer_status")
public static class Status implements Serializable{


    private static final long serialVersionUID = -2149364276152128818L;
    private int id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name="id")
    public int getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

@Entity
@Table(name="customer_salutation")
public static class Salutation implements Serializable{

    private static final long serialVersionUID = 4963516558091334778L;
    private int id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name="id")
    public int getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

@Entity
@Table(name="customer_language")
public static class Language implements Serializable{


    private static final long serialVersionUID = -5569029827581841931L;
    private int id;
    private String name;



    @Id
    @GeneratedValue
    @Column(name="id")
    public int getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

}

使用
session.load(Customer.class,customerId)
,而不是
session.get()
。它将创建一个惰性代理,假设客户存在,而不是从数据库中实际获取客户。

我终于找到了发生这种情况的原因。由于字段的获取类型是惰性的,因此除非实际使用该对象(例如,调用该对象的属性),否则不应获取该对象。 在这种情况下,并不是为产品设置客户导致运行所有不必要的查询。实际原因是响应中包含的对象。由于我最初没有在动作映射中指定要发送回调用方的对象,因此默认情况下,动作类(包括productbean)的所有属性都会发送回调用方。事实上,解决我问题的是以下几句简单的话:

<action name="updateProduct" class="net.scicom.seylan.view.ProductAction" method="saveOrUpdate">
        <result type="json">
            <param name="root">
                product
            </param>
        </result>
 </action>


经验教训:始终指定要在JSON调用中发送回调用方的对象

许多不必要的查询
这些查询是什么?检索客户对象属性的所有SELECT语句。我不明白为什么在我不使用这些属性时它必须检索这些属性。我想要实现的就是将customer对象设置为我的产品的所有者。谢谢您的回答。我已经在getCustomer方法中使用了Load,但仍然可以看到所有的查询正在运行。然后,如果我们看不到代码和查询,我不知道如何提供更多帮助。嗨,JB。非常感谢你的帮助。我刚刚编辑了问题并包含了所有相关代码和查询。请尝试删除对saveOrUpdate()的调用。这是没有用的,因为你的实体是附加的。我也试过了,但是查询仍然在运行。我注意到只有在为productbean设置客户时才会发生这种情况。因此,导致不必要的查询运行的不是CustomerManager.getCustomer(this.productCustomer),因为它们只在执行productbean.setCustomer(…)语句时运行。即使我尝试对检索到的customer对象的属性进行sysout,它也只运行一个查询来选择该属性。所以我猜不管它是什么,它都与我的setCustomer()方法有关。
Hibernate: select customer0_.id as id3_0_, customer0_.created_by as created23_3_0_, customer0_.status as status3_0_, customer0_.creation_date as creation2_3_0_, customer0_.first_name as first3_3_0_, customer0_.last_name as last4_3_0_, customer0_.salutation as salutation3_0_, customer0_.prfd_name as prfd5_3_0_, customer0_.nic as nic3_0_, customer0_.passport as passport3_0_, customer0_.mobile_num as mobile8_3_0_, customer0_.alter_num as alter9_3_0_, customer0_.email as email3_0_, customer0_.address_1 as address11_3_0_, customer0_.address_2 as address12_3_0_, customer0_.address_3 as address13_3_0_, customer0_.town as town3_0_, customer0_.district as district3_0_, customer0_.postal_code as postal16_3_0_, customer0_.prfd_language as prfd22_3_0_, customer0_.join_date as join17_3_0_, customer0_.dob as dob3_0_, customer0_.branch as branch3_0_, customer0_.rel_manager as rel20_3_0_ from customer customer0_ where customer0_.id=?
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.role as role0_0_, user0_.status as status0_0_, user0_.password as password0_0_, user0_.firstname as firstname0_0_, user0_.lastname as lastname0_0_ from user user0_ where user0_.id=?
Hibernate: select user_role0_.id as id2_0_, user_role0_.name as name2_0_ from user_roles user_role0_ where user_role0_.id=?
Hibernate: select user_statu0_.id as id1_0_, user_statu0_.name as name1_0_ from user_status user_statu0_ where user_statu0_.id=?
Hibernate: select interactio0_.customer_id as customer10_1_, interactio0_.id as id1_, interactio0_.id as id7_0_, interactio0_.interaction_type as interac11_7_0_, interactio0_.interaction_time as interact2_7_0_, interactio0_.interaction_date as interact3_7_0_, interactio0_.created_by as created13_7_0_, interactio0_.status as status7_0_, interactio0_.interaction_id as interact4_7_0_, interactio0_.channel_type as channel7_7_0_, interactio0_.interaction_categ1 as interac12_7_0_, interactio0_.interaction_categ2 as interact6_7_0_, interactio0_.escalated_to as escalated8_7_0_, interactio0_.notes as notes7_0_, interactio0_.customer_id as customer10_7_0_ from interaction interactio0_ where interactio0_.customer_id=?
Hibernate: select interactio0_.id as id10_0_, interactio0_.name as name10_0_, interactio0_.parent as parent10_0_ from interaction_categ1 interactio0_ where interactio0_.id=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select interactio0_.id as id8_0_, interactio0_.name as name8_0_ from interaction_type interactio0_ where interactio0_.id=?
Hibernate: select categs1x0_.parent as parent1_, categs1x0_.id as id1_, categs1x0_.id as id10_0_, categs1x0_.name as name10_0_, categs1x0_.parent as parent10_0_ from interaction_categ1 categs1x0_ where categs1x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select interactio0_.id as id9_0_, interactio0_.name as name9_0_ from interaction_channel_type interactio0_ where interactio0_.id=?
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.role as role0_0_, user0_.status as status0_0_, user0_.password as password0_0_, user0_.firstname as firstname0_0_, user0_.lastname as lastname0_0_ from user user0_ where user0_.id=?
Hibernate: select user_role0_.id as id2_0_, user_role0_.name as name2_0_ from user_roles user_role0_ where user_role0_.id=?
Hibernate: select user_statu0_.id as id1_0_, user_statu0_.name as name1_0_ from user_status user_statu0_ where user_statu0_.id=?
Hibernate: select interactio0_.id as id12_0_, interactio0_.name as name12_0_ from interaction_status interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id10_0_, interactio0_.name as name10_0_, interactio0_.parent as parent10_0_ from interaction_categ1 interactio0_ where interactio0_.id=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select interactio0_.id as id8_0_, interactio0_.name as name8_0_ from interaction_type interactio0_ where interactio0_.id=?
Hibernate: select categs1x0_.parent as parent1_, categs1x0_.id as id1_, categs1x0_.id as id10_0_, categs1x0_.name as name10_0_, categs1x0_.parent as parent10_0_ from interaction_categ1 categs1x0_ where categs1x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select categs2x0_.parent as parent1_, categs2x0_.id as id1_, categs2x0_.id as id11_0_, categs2x0_.name as name11_0_, categs2x0_.parent as parent11_0_ from interaction_categ2 categs2x0_ where categs2x0_.parent=?
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.role as role0_0_, user0_.status as status0_0_, user0_.password as password0_0_, user0_.firstname as firstname0_0_, user0_.lastname as lastname0_0_ from user user0_ where user0_.id=?
Hibernate: select interactio0_.id as id12_0_, interactio0_.name as name12_0_ from interaction_status interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id12_0_, interactio0_.name as name12_0_ from interaction_status interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id9_0_, interactio0_.name as name9_0_ from interaction_channel_type interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id12_0_, interactio0_.name as name12_0_ from interaction_status interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id9_0_, interactio0_.name as name9_0_ from interaction_channel_type interactio0_ where interactio0_.id=?
Hibernate: select interactio0_.id as id9_0_, interactio0_.name as name9_0_ from interaction_channel_type interactio0_ where interactio0_.id=?
Hibernate: select customer_l0_.id as id5_0_, customer_l0_.name as name5_0_ from customer_language customer_l0_ where customer_l0_.id=?
Hibernate: select products0_.account_holder as account5_1_, products0_.id as id1_, products0_.id as id13_0_, products0_.product_name as product2_13_0_, products0_.status as status13_0_, products0_.account_holder as account5_13_0_, products0_.account_num as account3_13_0_, products0_.account_limit as account4_13_0_ from product products0_ where products0_.account_holder=?
Hibernate: select product_st0_.id as id14_0_, product_st0_.name as name14_0_ from product_status product_st0_ where product_st0_.id=?
Hibernate: select customer_s0_.id as id4_0_, customer_s0_.name as name4_0_ from customer_salutation customer_s0_ where customer_s0_.id=?
Hibernate: select customer_s0_.id as id6_0_, customer_s0_.name as name6_0_ from customer_status customer_s0_ where customer_s0_.id=?
Committing the database transaction
Hibernate: update product set product_name=?, status=?, account_holder=?, account_num=?, account_limit=? where id=?
<action name="updateProduct" class="net.scicom.seylan.view.ProductAction" method="saveOrUpdate">
        <result type="json">
            <param name="root">
                product
            </param>
        </result>
 </action>
<action name="updateProduct" class="net.scicom.seylan.view.ProductAction" method="saveOrUpdate">
    </action>