一旦我创建了Hibernate SessionFactory,我无法关闭它并仍然连接到数据库

时间:2014-09-10 19:07:28

标签: java hibernate hibernate-envers

我正在使用Hibernate(4.1.7)和db2(1.3.166)一起使用Hibernate Envers

我的问题是,在我的recreateDatabase()方法中,我设置了数据库并创建了hibernate和hibernate审计(Envers)表,出于一些奇怪的原因,我不理解Envers表不会被创建,除非我配置了一个HibernateSessionFactory,即使在调用SchemaExport()之后才创建它。

真正的问题是任何关闭HibernateSessionFactory并重新创建的尝试都意味着它会抱怨它看不到任何hibernate表。

测试证明了这一点。

testRecreateHibernateTablesAndCreateSong()创建一个新数据库,然后将记录写入数据库并运行

testRecreateHibernateTablesAndCreateSong2()创建一个新的数据库,然后关闭hibernate会话工厂然后尝试创建一个新的hibernate会话工厂并将记录写入数据库但是失败了

Caused by: org.h2.jdbc.JdbcSQLException: Table "SONG" not found; SQL statement:
insert into Song (recNo, acoustidFingerprint, acoustidId, album, albumArtist, albumArtistSort, albumSort, amazonId, arranger, artist, artistSort, artists, barcode, bpm, catalogNo, comment, composer, composerSort, conductor, country, custom1, custom2, custom3, custom4, custom5, discNo, discSubtitle, discTotal, djmixer, duration, encoder, engineer, fbpm, filename, genre, grouping, isCompilation, isrc, keyOfSong, language, lastModified, lyricist, lyrics, matched, media, mixer, mood, musicbrainzArtistId, musicbrainzDiscId, musicbrainzOriginalReleaseId, musicbrainzRecordingId, musicbrainzReleaseArtistId, musicbrainzReleaseCountry, musicbrainzReleaseGroupId, musicbrainzReleaseId, musicbrainzReleaseStatus, musicbrainzReleaseTrackId, musicbrainzReleaseType, musicbrainzWorkId, musicipId, occasion, origFilename, originalAlbum, originalArtist, originalLyricist, originalYear, producer, quality, rating, recordLabel, releaseYear, remixer, script, subtitle, tags, tempo, title, titleSort, track, trackTotal, urlDiscogsArtistSite, urlDiscogsReleaseSite, urlLyricsSite, urlOfficialArtistSite, urlOfficialReleaseSite, urlWikipediaArtistSite, urlWikipediaReleaseSite, version) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [42102-166]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.command.Parser.readTableOrView(Parser.java:4757)
    at org.h2.command.Parser.readTableOrView(Parser.java:4735)
    at org.h2.command.Parser.parseInsert(Parser.java:958)
    at org.h2.command.Parser.parsePrepared(Parser.java:375)
    at org.h2.command.Parser.parse(Parser.java:279)
    at org.h2.command.Parser.parse(Parser.java:251)
    at org.h2.command.Parser.prepareCommand(Parser.java:217)
    at org.h2.engine.Session.prepareLocal(Session.java:415)
    at org.h2.engine.Session.prepareCommand(Session.java:364)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1111)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:266)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:1041)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask.run(GooGooStatementCache.java:525)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

现实世界的问题如下。

如果我启动应用程序并创建新数据库,我可以写它没问题。但是,如果我关闭应用程序并重新启动它现在无法找到数据库表(尽管它似乎能够连接)

更新我刚刚注意到在调用closeFactory()方法之后立即运行了SQL,它会删除所有表,这就是为什么它找不到SONG表,但为什么它会这样做呢!

以下完整自包含示例:

package com.jthink.songlayer.hibernate;

import com.jthink.songlayer.*;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class HibernateUtil
{
    private static AtomicInteger count = new AtomicInteger(0);
    private static SessionFactory factory;
    private static Logger logger;

    static
    {
        logger=Logger.getLogger("com.jthink.songlayer.hibernate.HibernateUtil");
    }

    private static void addEntitiesToConfig(Configuration config)
    {
        config.addAnnotatedClass(Song.class);
    }

    public static Configuration getInitializedConfiguration()
    {
        Configuration config = new Configuration();

        config.setProperty(Environment.DRIVER,"org.h2.Driver");
        config.setProperty(Environment.URL,"jdbc:h2:"+Db.DBFOLDER+"/"+Db.DBNAME+";FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE;CACHE_SIZE=50000");
        config.setProperty(Environment.DIALECT,"org.hibernate.dialect.H2Dialect");
        config.setProperty("hibernate.connection.username","jaikoz");
        config.setProperty("hibernate.connection.password","jaikoz");
        config.setProperty("hibernate.c3p0.numHelperThreads","10");
        config.setProperty("hibernate.c3p0.min_size","20");
        config.setProperty("hibernate.c3p0.max_size","100");
        config.setProperty("hibernate.c3p0.timeout","300");
        config.setProperty("hibernate.c3p0.maxStatementsPerConnection","50");
        config.setProperty("hibernate.c3p0.idle_test_period","3000");
        config.setProperty("hibernate.c3p0.acquireRetryAttempts","10");
        config.setProperty("hibernate.show_sql","true");
        //config.setProperty("org.hibernate.envers.audit_strategy", "org.hibernate.envers.strategy.ValidityAuditStrategy");
        config.setProperty("hibernate.format_sql","true");
        addEntitiesToConfig(config);
        return config;
    }

    public static Configuration getInitializedConfigurationAndRebuildAuditTables()
    {
        Configuration config = getInitializedConfiguration();
        config.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
        return config;
    }

    public static Session getSession()
    {
        logger.finest("********** BEGIN SESSION" + count.incrementAndGet());
        if (factory == null || factory.isClosed())
        {
            createFactory();
        }
        Session hibernateSession = factory.openSession();
        return hibernateSession;
    }

    private static void createFactory()
    {
        logger.severe("----Initilizing Hibernate Session factory");
        Configuration config = HibernateUtil.getInitializedConfiguration();
        factory = config.buildSessionFactory();
    }

    public static void closeSession(Session session)
    {
        logger.finest("********** CLOSE SESSION" + count.decrementAndGet());
        if(session.isOpen())
        {
            session.close();
        }
    }

    /**
     * Close the factory, allows the database to be deleted
     */
    public static void closeFactory()
    {
        if(factory!=null && !factory.isClosed())
        {
            logger.severe("----Closing Hibernate Session factory");
            factory.close();
        }
    }

    /**
      Schema Export creates the normal table, then building SessionFactory using the special configuration creates
      the audit table.
     */
    public static void recreateDatabase()
    {
        Configuration config;
        config =
                HibernateUtil.getInitializedConfigurationAndRebuildAuditTables();
        new SchemaExport(config).create(false,true);
        factory = config.buildSessionFactory();
    }

    public static Session beginTransaction()
    {

        Session hibernateSession;
        hibernateSession = HibernateUtil.getSession();
        hibernateSession.beginTransaction();
        return hibernateSession;
    }

    public static void commitTransaction()
    {
        HibernateUtil.getSession()
                .getTransaction().commit();
    }

    public static void rollbackTransaction()
    {
        HibernateUtil.getSession()
                .getTransaction().rollback();
    }

    public static void main(String args[])
    {
        System.out.println("ReCreateStart");
        HibernateUtil.recreateDatabase();
        System.out.println("ReCreateEnd");

    }

}

mport com.jthink.songlayer.CoverImage;
import com.jthink.songlayer.Song;
import com.jthink.songlayer.hibernate.Db;
import com.jthink.songlayer.hibernate.HibernateUtil;
import junit.framework.TestCase;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class RecreateDatabaseTest extends TestCase
{
    public void testRecreateHibernateTablesAndCreateSong() throws Exception
    {
        Exception e = null;
        try
        {
            HibernateUtil.recreateDatabase();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            e = ex;
        }
        assertNull(e);
        createSong();
    }

    public void testRecreateHibernateTablesAndCreateSong2()throws Exception
    {
        Exception e = null;
        try
        {
            HibernateUtil.recreateDatabase();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            e = ex;
        }
        assertNull(e);

        HibernateUtil.closeFactory();

        createSong();
    }


    public void createSong() throws Exception
    {

        Exception ex = null;
        try
        {
            Session session = HibernateUtil.getSession();
            Transaction tx = session.beginTransaction();
            Song song = new Song();
            song.setComposer("composer");
            session.save(song);
            tx.commit();
        }
        catch (Exception e)
        {
            ex = e;
            e.printStackTrace();
        }
        assertNull(ex);
    }
}

0 个答案:

没有答案