0

我有两个名为 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;
}

在为特定产品设置客户时(更新产品时),我通过客户 ID 加载客户,如下所示:

productbean.setCustomer(CustomerManager.getCustomer(this.productCustomer));
ProductManager.saveOrUpdate(productbean);

现在我的问题是,为该产品设置客户会导致运行许多不必要的查询。仅当我尝试设置客户时才会发生这种情况。我想知道是否有任何方法可以避免这种情况。感谢您对此的任何帮助。

这是我的 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;
    }

}

}

这是我的休眠日志,显示所有正在运行的查询:

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=?
4

2 回答 2

1

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

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

注意:product对象不同于productbean. Product是一个类的对象,ProductViewModel它是我们从数据库中得到的结果被转换成的类。

最初我的 updateProduct 映射看起来像这样,这是问题的来源:

<action name="updateProduct" class="net.scicom.seylan.view.ProductAction" method="saveOrUpdate">
    </action>

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

于 2013-11-28T04:20:45.180 回答
1

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

于 2013-11-05T12:19:44.230 回答