有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Hibernate期间清理连接池花费的时间太长

我第一次在Hibernate中尝试多对一关联映射。我有两个POJO类——Employee和Address——它们之间的关联是一个Address对象可以与多个Employee对象相关联

我的程序从来没有编译过,它总是卡在堆栈跟踪的这一点上-

Jun 25, 2020 12:41:09 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.3.1.Final}
Jun 25, 2020 12:41:09 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Jun 25, 2020 12:41:09 AM org.hibernate.spatial.integration.SpatialService <init>
INFO: HHH80000001: hibernate-spatial integration enabled : true
Jun 25, 2020 12:41:09 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.3.Final}
Jun 25, 2020 12:41:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Jun 25, 2020 12:41:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/hibernatedb2]
Jun 25, 2020 12:41:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=root}
Jun 25, 2020 12:41:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Jun 25, 2020 12:41:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Jun 25, 2020 12:41:10 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Jun 25, 2020 12:41:10 AM org.hibernate.envers.boot.internal.EnversServiceImpl configure
INFO: Envers integration enabled? : true
Jun 25, 2020 12:41:11 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@7a18e8d] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Jun 25, 2020 12:41:11 AM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Jun 25, 2020 12:41:11 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost/hibernatedb2]

地址。爪哇-

package firsthb;

public class Address {
    
    private int id;
    private String street, city, state;
    
    //getters and setters
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getStreet() {
        return street;
    }
    
    public void setStreet(String street) {
        this.street = street;
    }
    
    public String getCity() {
        return city;
    }
    
    public void setCity(String city) {
        this.city = city;
    }
    
    public String getState() {
        return state;
    }
    
    public void setState(String state) {
        this.state = state;
    }
}

雇员。爪哇-

package firsthb;

public class Employee {

    private int id;
    private String firstName, lastName;
    private Address address;
    
    //getters and setters
    public int getId() {    
        return id;  
    }
    
    public void setId(int id) { 
        this.id = id;
    }
    
    public String getFirstName() {
        return firstName;
    }
    
    public void setFirstName(String firstName) {    
        this.firstName = firstName;
    }
    
    public String getLastName() {
        return lastName;
    }
    
    public void setLastName(String lastName) {  
        this.lastName = lastName;
    }
    
    public Address getAddress() {
        return address;
    }
    
    public void setAddress(Address address) {
        this.address = address;
    }
}

雇员。哈佛商学院。xml(Hibernate映射文件)-

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "<a class='vglnk' href='http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd' rel='nofollow'><span>http</span><span>://</span><span>hibernate</span><span>.</span><span>sourceforge</span><span>.</span><span>net</span><span>/</span><span>hibernate</span><span>-</span><span>mapping</span><span>-</span><span>3</span><span>.</span><span>0</span><span>.</span><span>dtd</span></a>">
<hibernate-mapping>

<class name="firsthb.Employee" table="EMP">
    <meta attribute="class-description">
    This class contains employees' details
    </meta>

    <id column="ID" name="id" type="int">
        <generator class="native" />
    </id>

    <property column="FIRST_NAME" name="firstName" type="string"/>
    <property column="LAST_NAME" name="lastName" type="string"/>

    <many-to-one name="address" column="address" class="firsthb.Address" not-null="true"/>
    <!-- Attributes in <many-to-one> tag - 
        1. name: data member in parent class
        2. column: column name in parent table -->

</class>

<class name="firsthb.Address" table="ADDRESS">
    <meta attribute="class-description">
    This class contains the addresses of employees
    </meta>
    
    <id name="id" column="ID" type="int">
        <generator class="native"/>
    </id>
    
    <property name="street" column="street_name" type="string"/>
    <property name="city" column="city_name" type="string"/>
    <property name="state" column="state_name" type="string"/>

</class>

</hibernate-mapping>

冬眠。cfg。xml(Hibernate配置文件)-

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 5.3//EN"  
          "http://www.hibernate.org/dtd/hibernate-configuration-5.3.dtd">  

   
<hibernate-configuration>  
  
    <session-factory>  
        
        <property name="hbm2ddl.auto">update</property>  
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>  
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
        <property name="connection.url">jdbc:mysql://localhost/hibernatedb2</property>  
        <property name="connection.username">root</property>    
    <mapping resource="employee.hbm.xml"/>
    </session-factory>  
  
</hibernate-configuration>  

最后是我实现多对一关联功能的文件-

package firsthb;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;  
import org.hibernate.SessionFactory;  
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; //new - so that line 24 works, and StandardServiceRegistry + metadata initialization can be avoided
/*
import org.hibernate.boot.Metadata;  
import org.hibernate.boot.MetadataSources;  
import org.hibernate.boot.registry.StandardServiceRegistry;  
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 */

@SuppressWarnings({"deprecation", "unchecked"})
public class FunctionalityImplementer {
    
    private static SessionFactory factory;

    public static void main(String[] args) {
        
        factory = new Configuration().configure().buildSessionFactory();
        
        FunctionalityImplementer fi = new FunctionalityImplementer();
        Address addr1 = fi.addAddress("E-85, DDA Flats", "New Delhi", "Delhi");
        Employee emp1 = fi.addEmployee("Vikramaditya", "Bhatnagar", addr1);
        Employee emp2 = fi.addEmployee("Yashaswani", "Bhatnagar", addr1);
        fi.listEmployees();
        
        //Address addr1 = ME.add
        
        //System.out.println("Successfully saved");
        factory.close();
    }
    
    public Address addAddress(String street, String city, String state) {
        
        //StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
        //Metadata meta = new MetadataSources(ssr).getMetadataBuilder().build();
        //factory = meta.getSessionFactoryBuilder().build();
        
        Session session = factory.openSession();
        Transaction t = session.beginTransaction();
        
        Address a = new Address(); //better programming practice would be to use a parameterized constructor instead of individual setters
        a.setStreet(street);
        a.setCity(city);
        a.setState(state);
        
        t.commit();
        session.close();
        return a;
    }
    
    public Employee addEmployee(String firstName, String lastName, Address address) {
        
        Session session = factory.openSession();
        Transaction t = session.beginTransaction();
        
        Employee e = new Employee(); //better programming practice would be to use a parameterized constructor instead of individual setters
        e.setFirstName(firstName);
        e.setLastName(lastName);
        e.setAddress(address);
        
        t.commit();
        session.close();
        return e;
    }
    
    
    public void listEmployees() {
        
        Session session = factory.openSession();
        Transaction t = session.beginTransaction();
        
        List<Employee> elist = new ArrayList<>();
        Query<Employee> query = session.createQuery("From Employee");
        elist = (ArrayList<Employee>)query.list();
        
        for(Employee loopctr : elist) {
            System.out.println("EMPLOYEE DETAILS -");
            System.out.println(loopctr.getId() + "\t" + loopctr.getFirstName() + "\t" + loopctr.getLastName());
            System.out.println("ADDRESS DETAILS -");
            Address addr = loopctr.getAddress();
            System.out.println(addr.getStreet() + "\t" + addr.getCity() + "\t" + addr.getState());
        }
        
        t.commit();
        session.close();
    }
}

我在某个地方读到,如果在整个程序中创建多个SessionFactory对象(因为SessionFactory对象的大小很大),这样的程序可能需要很长时间才能编译。然而,这里的情况也不是这样,因为我创建了一个SessionFactory对象,其作用域为整个FunctionityImplementer类,并且在创建过程中创建了多个会话对象(据我所知,这很好,因为它们的大小较小)

请注意,在这一点上,表是在MySQL控制台中创建的(编译开始时,RDBMS中不存在表)-

describe emp;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| ID         | int(11)      | NO   | PRI | NULL    | auto_increment |
| FIRST_NAME | varchar(255) | YES  |     | NULL    |                |
| LAST_NAME  | varchar(255) | YES  |     | NULL    |                |
| address    | int(11)      | NO   | MUL | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.30 sec)

mysql> desc address;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| ID          | int(11)      | NO   | PRI | NULL    | auto_increment |
| street_name | varchar(255) | YES  |     | NULL    |                |
| city_name   | varchar(255) | YES  |     | NULL    |                |
| state_name  | varchar(255) | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0.03 sec) 

共 (1) 个答案

  1. # 1 楼答案

    找到答案了!很简单,我只是忘了加上 session.save(a);session.save(em); 就在2个数据添加函数中的t.commit();语句之前

    从那以后工作得很有魅力