简体   繁体   中英

fetching data from hibernate db takes too long

how can I boost the performance? when requesting data from the stackoverflow or gituhb rest api, it takes miliseconds to get a response but for my small application it takes 3-5 seconds for each request.

Example:

@XmlRootElement
@Entity
@Table(name = "customers")
public class Customer extends Model {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

@Column(name = "name")
private String name;

@Column(name = "email")
private String email;

@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name = "address_id")
private Address address;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private List<Booking> bookings;

/**
 * Constructor.
 *
 */
public Customer() {}

/**
 * Constructor.
 *
 * @param email Email of the customer.
 * @param address Address of the customer.
 * @param name Name of the customer.
 */
public Customer(String email, Address address, String name) {
    this.email = email;
    this.address = address;
    this.name = name;
}

/**
 * Set the id of the customer.
 *
 */
public void setId(int id) {
    this. id = id;
}

/**
 * Get the id of the customer.
 *
 * @return Id of the customer.
 */
public int getId() {
    return id;
}

/**
 * Get the name of the customer.
 *
 * @return Name of the customer.
 */
public String getName() {
    return name;
}

/**
 * Set the name of the customer.
 *
 * @param name New name of the customer.
 */
public void setName(String name) {
    this.name = name;
}

/**
 * Get the email of the customer
 *
 * @return Email of the customer.
 */
public String getEmail() {
    return email;
}

/**
 * Set the email of the customer
 *
 * @param email New email of the customer.
 */
public void setEmail(String email) {
    this.email = email;
}

/**
 * Get the address of the customer
 *
 * @return Address of the customer.
 */
public Address getAddress() {
    return address;
}

/**
 * Set the address of the customer
 *
 * @param address New address of the customer.
 */
public void setAddress(Address address) {
    this.address = address;
}

/**
 * Get the bookings of the customer.
 *
 * @return List of bookings.
 */
@XmlTransient
public List<Booking> getBookings() {
    return bookings;
}

/**
 * Set the bookings of the customer.
 *
 * @param bookings List of bookings.
 */
public void setBookings(List<Booking> bookings) {
    this.bookings = bookings;
}

/**
 * Get all customers from the database.
 *
 * @return List of customers.
 */
public static List<Customer> all() {
    return (List<Customer>) Database.all(Customer.class);
}

/**
 * Find a customer by the id.
 *
 * @param id Id of the customer.
 * @return The customer object. Returns null if no customers were found.
 */
public static Customer find(int id) {
    return (Customer) Database.find(Customer.class, id);
}

/**
 * Check if a given customer id already exists.
 *
 * @param id Id of the customer.
 * @return Boolean.
 */
public static boolean exists(int id) {
    return Database.exists(Customer.class, id);
}

/**
 * Find customers by a specific column value.
 *
 * @param column Column of the database table.
 * @param value Value of the column.
 * @return List of customers.
 */
public static List<Customer> where(String column, String value) {
    return (List<Customer>) Database.where(Customer.class, column, value);
}

}

Database class:

public class Database {

/**
 * Get all objects of a model from the database.
 *
 * @param model Class type of the model.
 * @return List of all model objects.
 */
public static List<? extends Model> all(Class<? extends Model> model) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    List<Model> list = (List<Model>) entityManager.createQuery("from " + model.getName(), model).getResultList();
    entityManager.close();
    return list;
}

/**
 * Find a model object by the id.
 *
 * @param model Class type of the model.
 * @param id Id of the model object.
 * @return The model object. Returns null if no objects were found.
 */
public static Model find(Class<? extends Model> model, int id) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    Model m = entityManager.find(model, id);
    entityManager.close();
    return m;
}

/**
 * Check if a given model object id already exists.
 *
 * @param model Class type of the model.
 * @param id Id of the model object.
 * @return Boolean.
 */
public static boolean exists(Class<? extends Model> model, int id) {
    return Database.find(model, id) != null;
}

/**
 * Find model objects by a specific column value.
 *
 * @param model Class type of the model.
 * @param column Column of the database table.
 * @param value Value of the column.
 * @return List of model objects.
 */
public static List<? extends Model> where(Class<? extends Model> model, String column, String value) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    Query query = entityManager.createQuery("from " + model.getName() + " where " + column + "=:value");
    return (List<? extends Model>) query.setParameter("value", value).getResultList();
}
}

HibernateUtil class:

public class HibernateUtil {

private static EntityManagerFactory entityManagerFactory;

static {

    entityManagerFactory = Persistence.createEntityManagerFactory("com.travelagency.jpa");

}

/**
 * Get the EntityManager Factory object.
 *
 * @return EntityManagerFactory object.
 */
public static EntityManagerFactory getEntityManagerFactory() {
    return entityManagerFactory;
}
}

thank you

Your main problem is that you use Hibernate as if it was ActiveRecord framework, which is wrong. But as a quick term solution, you don't need to recreate EntityManager every time. That's what takes you so long. Create it only once, and don't close it.

From your code I can see you apply no paging to the query's you do. This basically means you load the entire table into memory. I'm not sure how big your tables are, but paging might be a solution.

int offset = 0;
int limit = 10;

Query query = entityManager.createQuery("from " + model.getName() + " where " + column + "=:value");
query.setFirstResult(offset);
query.setMaxResults(limit);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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