问题描述
我正在使用maven,jpa,spring和hibernate进行项目.
类TopicFacadeTest需要20分钟的时间o_O
插入和删除非常慢.
CPU在1%到3%之间.
我有6G的RAM.
有什么问题??这很正常吗?
该数据库最初是空的.
I'm doing a project with maven, jpa, spring and hibernate.
The class TopicFacadeTest takes 20 minutes o_O
Inserts and deletes are very slow.
The CPU is between 1% and 3%.
I have 6G of RAM.
What's the problem?? this is normal?
The database is initially empty.
这些是配置文件:
persistence.xml
These are the configuration files:
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mycompanyPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
</persistence>
test-context.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- holding properties for database connectivity /-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- enabling annotation driven configuration /-->
<context:annotation-config/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
<property name="persistenceUnitName" value="mycompanyPU"></property>
</bean>
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}"
p:showSql="${jpa.showSql}"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.mycompany.repository" />
<context:component-scan base-package="com.mycompany.service" />
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.1.12:3306/mydatabase
jdbc.username=root
jdbc.password=root
hibernate.dialect=org.hibernate.dialect.MySQLDialect
jpa.database = MYSQL
hibernate.generate_statistics = true
hibernate.show_sql = true
jpa.showSql = true
jpa.generateDdl = true
Java类:
Topic.java
package com.mycompany.domain;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name = "topic")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = Topic.FIND_ALL, query = "SELECT t FROM Topic t"),
@NamedQuery(name = Topic.FIND_BY_ID, query = "SELECT t FROM Topic t WHERE t.id = :id"),
@NamedQuery(name = Topic.FIND_BY_NAME, query = "SELECT t FROM Topic t WHERE t.name = :name"),
@NamedQuery(name = Topic.FIND_BY_ID_CHAR, query = "SELECT t FROM Topic t WHERE t.idChar = :idChar")})
public class Topic implements Serializable {
private static final long serialVersionUID = 1L;
public static final String FIND_ALL = "Topic.findAll";
public static final String FIND_BY_ID = "Topic.findById";
public static final String FIND_BY_NAME = "Topic.findByName";
public static final String FIND_BY_ID_CHAR = "Topic.findByIdChar";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Basic(optional = false)
@Column(name = "id", unique = true, insertable = false, updatable = false)
private Long id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "name")
private String name;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "idChar")
private String idChar;
public Topic() {
}
public Topic(String name, String idChar) {
this.name = name;
this.idChar = idChar;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdChar() {
return idChar;
}
public void setIdChar(String idChar) {
this.idChar = idChar;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Topic)) {
return false;
}
Topic other = (Topic) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.mycompany.domain.Topic[ id=" + id + " ]";
}
}
AbstractFacade.java
package com.mycompany.repository;
import java.util.List;
import javax.persistence.EntityManager;
import org.springframework.transaction.annotation.Transactional;
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
@Transactional
public void create(T entity) {
if (entity != null) {
getEntityManager().persist(entity);
}
}
@Transactional
public void edit(T entity) {
if (entity != null) {
getEntityManager().merge(entity);
}
}
@Transactional
public void remove(T entity) {
if (entity != null) {
getEntityManager().remove(getEntityManager().merge(entity));
}
}
@Transactional(readOnly = true)
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
@Transactional(readOnly = true)
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
@Transactional(readOnly = true)
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
@Transactional(readOnly = true)
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
TopicFacade
package com.mycompany.repository;
//<editor-fold defaultstate="collapsed" desc="imports">
import com.mycompany.domain.Topic;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
//</editor-fold>
@Stateless
@Repository
public class TopicFacade extends AbstractFacade<Topic> implements TopicFacadeLocal {
@PersistenceContext
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public TopicFacade() {
super(Topic.class);
}
@Transactional(readOnly = true)
@Override
public Topic findByName(String name) {
try {
Query query = em.createNamedQuery(Topic.FIND_BY_NAME);
query.setParameter("name", name);
return (Topic) query.getSingleResult();
} catch (NoResultException ex) {
return null;
}
}
@Transactional(readOnly = true)
@Override
public List<Topic> findByIdChar(String t) {
Query query = em.createNamedQuery(Topic.FIND_BY_ID_CHAR);
query.setParameter("idChar", t);
return query.getResultList();
}
}
TopicFacadeTest.java
package com.mycompany.repository;
//<editor-fold defaultstate="collapsed" desc="imports">
import com.mycompany.domain.Topic;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.embeddable.EJBContainer;
import junit.framework.Assert;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//</editor-fold>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class TopicFacadeTest {
//<editor-fold defaultstate="collapsed" desc="attributes">
@Autowired()
private TopicFacade topicFacade;
private Topic topic0;
private Topic topic1;
private Topic topic2;
private Topic topic3;
private Topic topic4;
private Topic topic5;
private Topic topic6;
private Topic topic7;
private Topic topic8;
private Topic topic9;
private List<Topic> topics;
//</editor-fold>
public TopicFacadeTest() {
}
//<editor-fold defaultstate="collapsed" desc="testCycle">
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
topic0 = new Topic("tema0", "t");
topic1 = new Topic("tema1", "t");
topic2 = new Topic("tema2", "t");
topic3 = new Topic("tema3", "t");
topic4 = new Topic("tema4", "t");
topic5 = new Topic("tema5", "t");
topic6 = new Topic("tema6", "t");
topic7 = new Topic("tema7", "t");
topic8 = new Topic("tema8", "d");
topic9 = new Topic("tema9", "k");
topicFacade.create(topic0);
topicFacade.create(topic1);
topicFacade.create(topic2);
topicFacade.create(topic3);
topicFacade.create(topic4);
topicFacade.create(topic5);
topicFacade.create(topic6);
topicFacade.create(topic7);
topicFacade.create(topic8);
topicFacade.create(topic9);
topics = new ArrayList();
topics.add(topic0);
topics.add(topic1);
topics.add(topic2);
topics.add(topic3);
topics.add(topic4);
topics.add(topic5);
topics.add(topic6);
topics.add(topic7);
topics.add(topic8);
topics.add(topic9);
}
@After
public void tearDown() {
topicFacade.remove(topic0);
topicFacade.remove(topic1);
topicFacade.remove(topic2);
topicFacade.remove(topic3);
topicFacade.remove(topic4);
topicFacade.remove(topic5);
topicFacade.remove(topic6);
topicFacade.remove(topic7);
topicFacade.remove(topic8);
topicFacade.remove(topic9);
topic0 = null;
topic1 = null;
topic2 = null;
topic3 = null;
topic4 = null;
topic5 = null;
topic6 = null;
topic7 = null;
topic8 = null;
topic9 = null;
topics = null;
}
//</editor-fold>
/**
* Test of create method, of class TopicFacade.
*/
@org.junit.Test
public void testCreate() throws Exception {
System.out.println("create");
Topic topic = new Topic();
topic.setName("tema99");
topic.setIdChar("t");
topicFacade.create(topic);
assertTrue(true);
topicFacade.remove(topic);
}
/**
* Test of edit method, of class TopicFacade.
*/
@org.junit.Test
public void testEdit() throws Exception {
System.out.println("edit");
topic1.setIdChar("vf");
topicFacade.edit(topic1);
assertTrue(true);
assertEquals("vf", topicFacade.find(topic1.getId()).getIdChar());
}
/**
* Test of remove method, of class TopicFacade.
*/
@org.junit.Test
public void testRemove() throws Exception {
System.out.println("remove");
topicFacade.remove(topic0);
assertEquals(null, topicFacade.find(topic0.getId()));
}
/**
* Test of find method, of class TopicFacade.
*/
@org.junit.Test
public void testFind() throws Exception {
System.out.println("find");
assertEquals(topic0, topicFacade.find(topic0.getId()));
assertNotSame(topic0, topicFacade.find(topic1.getId()));
assertEquals(null, topicFacade.find(null));
assertEquals(null, topicFacade.find(-747474));
}
/**
* Test of findAll method, of class TopicFacade.
*/
@org.junit.Test
public void testFindAll() throws Exception {
System.out.println("findAll");
List<Topic> topicsFindAll = topicFacade.findAll();
assertNotNull(topicsFindAll);
assertEquals(10, topicsFindAll.size());
}
/**
* Test of findRange method, of class TopicFacade.
*/
@org.junit.Test
public void testFindRange() throws Exception {
System.out.println("findRange");
int[] range = {4, 10};
List<Topic> topics = topicFacade.findRange(range);
for (Topic topic : topics) {
System.out.println(topic);
}
}
/**
* Test of count method, of class TopicFacade.
*/
@org.junit.Test
public void testCount() throws Exception {
System.out.println("count");
assertEquals(10, topicFacade.count());
tearDown();
assertEquals(0, topicFacade.count());
}
/**
* Test of findByName method, of class TopicFacade.
*/
@Test
public void testFindByName() throws Exception {
System.out.println("findByName");
assertEquals(topic0, topicFacade.findByName("tema0"));
assertNotSame(topic0, topicFacade.findByName("tema1"));
assertNotSame(null, topicFacade.findByName("tema0"));
assertEquals(null, topicFacade.findByName("jafasdg"));
}
/**
* Test of findByIdChar method, of class TopicFacade.
*/
@Test
public void testFindByIdChar() throws Exception {
System.out.println("findByIdChar");
List<Topic> topicsByIdChar = topicFacade.findByIdChar("t");
assertEquals(8, topicsByIdChar.size());
for (Topic topic : topicsByIdChar) {
System.out.println(String.format("%s-%s", topic.getId(), topic.getIdChar()));
}
tearDown();
topicsByIdChar = null;
topicsByIdChar = topicFacade.findByIdChar("t");
assertTrue(true);
}
}
已可能的解决方案|数据源(连接池),添加依赖项
test-context.xml
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
pom.xml
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>7.0.39</version>
</dependency>
推荐答案
首先,将DriverManagerDataSource
替换为实际汇集连接的数据源.该数据源只是委托给驱动程序管理器来打开/关闭每个事务的连接
For start, replace DriverManagerDataSource
with a data source which actually pools connections. This data source just delegate to the Driver Manager to open\close a connection per transaction
这篇关于Maven + JPA +休眠+春天.太慢了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!